blob: da92be3fca5acd2f370ed3da4d873a020242f37a [file] [log] [blame]
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +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 Feistb49ac872019-05-21 15:12:01 -070018#include "health.hpp"
James Feist1c8fba92019-12-20 15:12:07 -080019#include "led.hpp"
Jason M. Billsf5c9f8b2018-12-18 16:51:18 -080020#include "pcie.hpp"
Jennifer Leec5d03ff2019-03-08 15:42:58 -080021#include "redfish_util.hpp"
22
Ed Tanous9712f8a2018-09-21 13:38:49 -070023#include <boost/container/flat_map.hpp>
24#include <node.hpp>
Andrew Geisslercb7e1e72019-02-19 13:05:38 -060025#include <utils/fw_utils.hpp>
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020026#include <utils/json_utils.hpp>
Gunnar Mills1214b7e2020-06-04 10:11:30 -050027
Ed Tanousabf2add2019-01-22 16:40:12 -080028#include <variant>
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020029
Ed Tanous1abe55e2018-09-05 08:30:59 -070030namespace redfish
31{
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020032
Alpana Kumari9d3ae102019-04-12 06:49:32 -050033/**
34 * @brief Updates the Functional State of DIMMs
35 *
36 * @param[in] aResp Shared pointer for completing asynchronous calls
37 * @param[in] dimmState Dimm's Functional state, true/false
38 *
39 * @return None.
40 */
Ed Tanous23a21a12020-07-25 04:45:05 +000041inline void updateDimmProperties(std::shared_ptr<AsyncResp> aResp,
42 const std::variant<bool>& dimmState)
Alpana Kumari9d3ae102019-04-12 06:49:32 -050043{
Gunnar Mills1214b7e2020-06-04 10:11:30 -050044 const bool* isDimmFunctional = std::get_if<bool>(&dimmState);
Alpana Kumari9d3ae102019-04-12 06:49:32 -050045 if (isDimmFunctional == nullptr)
46 {
47 messages::internalError(aResp->res);
48 return;
49 }
Gunnar Mills698654b2019-10-16 13:17:37 -050050 BMCWEB_LOG_DEBUG << "Dimm Functional: " << *isDimmFunctional;
Alpana Kumari9d3ae102019-04-12 06:49:32 -050051
Gunnar Mills4e0453b2020-07-08 14:00:30 -050052 // Set it as Enabled if at least one DIMM is functional
Alpana Kumari9d3ae102019-04-12 06:49:32 -050053 // Update STATE only if previous State was DISABLED and current Dimm is
54 // ENABLED.
Gunnar Mills1214b7e2020-06-04 10:11:30 -050055 nlohmann::json& prevMemSummary =
Alpana Kumari9d3ae102019-04-12 06:49:32 -050056 aResp->res.jsonValue["MemorySummary"]["Status"]["State"];
57 if (prevMemSummary == "Disabled")
58 {
59 if (*isDimmFunctional == true)
60 {
61 aResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
62 "Enabled";
63 }
64 }
65}
66
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050067/*
68 * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState
69 *
70 * @param[in] aResp Shared pointer for completing asynchronous calls
71 * @param[in] cpuPresenceState CPU present or not
72 *
73 * @return None.
74 */
Ed Tanous23a21a12020-07-25 04:45:05 +000075inline void modifyCpuPresenceState(std::shared_ptr<AsyncResp> aResp,
76 const std::variant<bool>& cpuPresenceState)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050077{
Gunnar Mills1214b7e2020-06-04 10:11:30 -050078 const bool* isCpuPresent = std::get_if<bool>(&cpuPresenceState);
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050079
80 if (isCpuPresent == nullptr)
81 {
82 messages::internalError(aResp->res);
83 return;
84 }
Gunnar Mills698654b2019-10-16 13:17:37 -050085 BMCWEB_LOG_DEBUG << "Cpu Present: " << *isCpuPresent;
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050086
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050087 if (*isCpuPresent == true)
88 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -050089 nlohmann::json& procCount =
James Feistb4b95952019-12-05 15:01:55 -080090 aResp->res.jsonValue["ProcessorSummary"]["Count"];
91 auto procCountPtr =
Gunnar Mills1214b7e2020-06-04 10:11:30 -050092 procCount.get_ptr<nlohmann::json::number_integer_t*>();
James Feistb4b95952019-12-05 15:01:55 -080093 if (procCountPtr != nullptr)
94 {
95 // shouldn't be possible to be nullptr
96 *procCountPtr += 1;
97 }
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050098 }
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050099}
100
101/*
102 * @brief Update "ProcessorSummary" "Status" "State" based on
103 * CPU Functional State
104 *
105 * @param[in] aResp Shared pointer for completing asynchronous calls
106 * @param[in] cpuFunctionalState is CPU functional true/false
107 *
108 * @return None.
109 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000110inline void
111 modifyCpuFunctionalState(std::shared_ptr<AsyncResp> aResp,
112 const std::variant<bool>& cpuFunctionalState)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500113{
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500114 const bool* isCpuFunctional = std::get_if<bool>(&cpuFunctionalState);
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500115
116 if (isCpuFunctional == nullptr)
117 {
118 messages::internalError(aResp->res);
119 return;
120 }
Gunnar Mills698654b2019-10-16 13:17:37 -0500121 BMCWEB_LOG_DEBUG << "Cpu Functional: " << *isCpuFunctional;
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500122
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500123 nlohmann::json& prevProcState =
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500124 aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"];
125
Gunnar Mills4e0453b2020-07-08 14:00:30 -0500126 // Set it as Enabled if at least one CPU is functional
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500127 // Update STATE only if previous State was Non_Functional and current CPU is
128 // Functional.
129 if (prevProcState == "Disabled")
130 {
131 if (*isCpuFunctional == true)
132 {
133 aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
134 "Enabled";
135 }
136 }
137}
138
139/*
Ed Tanous6c34de42018-08-29 13:37:36 -0700140 * @brief Retrieves computer system properties over dbus
141 *
142 * @param[in] aResp Shared pointer for completing asynchronous calls
143 * @param[in] name Computer system name from request
144 *
145 * @return None.
146 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000147inline void getComputerSystem(std::shared_ptr<AsyncResp> aResp,
148 std::shared_ptr<HealthPopulate> systemHealth)
Ed Tanous6c34de42018-08-29 13:37:36 -0700149{
Ed Tanous6c34de42018-08-29 13:37:36 -0700150 BMCWEB_LOG_DEBUG << "Get available system components.";
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500151
Ed Tanous6c34de42018-08-29 13:37:36 -0700152 crow::connections::systemBus->async_method_call(
James Feist5bc2dc82019-10-22 14:33:16 -0700153 [aResp, systemHealth](
Ed Tanous6c34de42018-08-29 13:37:36 -0700154 const boost::system::error_code ec,
155 const std::vector<std::pair<
156 std::string,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500157 std::vector<std::pair<std::string, std::vector<std::string>>>>>&
158 subtree) {
Ed Tanous6c34de42018-08-29 13:37:36 -0700159 if (ec)
160 {
161 BMCWEB_LOG_DEBUG << "DBUS response error";
Jason M. Billsf12894f2018-10-09 12:45:45 -0700162 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700163 return;
164 }
Ed Tanous6c34de42018-08-29 13:37:36 -0700165 // Iterate over all retrieved ObjectPaths.
166 for (const std::pair<std::string,
167 std::vector<std::pair<
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500168 std::string, std::vector<std::string>>>>&
169 object : subtree)
Ed Tanous6c34de42018-08-29 13:37:36 -0700170 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500171 const std::string& path = object.first;
Ed Tanous6c34de42018-08-29 13:37:36 -0700172 BMCWEB_LOG_DEBUG << "Got path: " << path;
173 const std::vector<
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500174 std::pair<std::string, std::vector<std::string>>>&
175 connectionNames = object.second;
Ed Tanous6c34de42018-08-29 13:37:36 -0700176 if (connectionNames.size() < 1)
177 {
178 continue;
179 }
Ed Tanous029573d2019-02-01 10:57:49 -0800180
James Feist5bc2dc82019-10-22 14:33:16 -0700181 auto memoryHealth = std::make_shared<HealthPopulate>(
182 aResp, aResp->res.jsonValue["MemorySummary"]["Status"]);
183
184 auto cpuHealth = std::make_shared<HealthPopulate>(
185 aResp, aResp->res.jsonValue["ProcessorSummary"]["Status"]);
186
187 systemHealth->children.emplace_back(memoryHealth);
188 systemHealth->children.emplace_back(cpuHealth);
189
Ed Tanous029573d2019-02-01 10:57:49 -0800190 // This is not system, so check if it's cpu, dimm, UUID or
191 // BiosVer
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500192 for (const auto& connection : connectionNames)
Ed Tanous6c34de42018-08-29 13:37:36 -0700193 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500194 for (const auto& interfaceName : connection.second)
Ed Tanous6c34de42018-08-29 13:37:36 -0700195 {
Ed Tanous029573d2019-02-01 10:57:49 -0800196 if (interfaceName ==
197 "xyz.openbmc_project.Inventory.Item.Dimm")
Ed Tanous6c34de42018-08-29 13:37:36 -0700198 {
Ed Tanous029573d2019-02-01 10:57:49 -0800199 BMCWEB_LOG_DEBUG
200 << "Found Dimm, now get its properties.";
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500201
Ed Tanous029573d2019-02-01 10:57:49 -0800202 crow::connections::systemBus->async_method_call(
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500203 [aResp, service{connection.first},
204 path(std::move(path))](
Ed Tanouscb13a392020-07-25 19:02:03 +0000205 const boost::system::error_code ec2,
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500206 const std::vector<
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500207 std::pair<std::string, VariantType>>&
208 properties) {
Ed Tanouscb13a392020-07-25 19:02:03 +0000209 if (ec2)
Ed Tanous029573d2019-02-01 10:57:49 -0800210 {
211 BMCWEB_LOG_ERROR
Ed Tanouscb13a392020-07-25 19:02:03 +0000212 << "DBUS response error " << ec2;
Ed Tanous029573d2019-02-01 10:57:49 -0800213 messages::internalError(aResp->res);
214 return;
215 }
216 BMCWEB_LOG_DEBUG << "Got "
217 << properties.size()
Gunnar Mills698654b2019-10-16 13:17:37 -0500218 << " Dimm properties.";
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500219
220 if (properties.size() > 0)
Ed Tanous029573d2019-02-01 10:57:49 -0800221 {
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500222 for (const std::pair<std::string,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500223 VariantType>&
224 property : properties)
Ed Tanous6c34de42018-08-29 13:37:36 -0700225 {
Cheng C Yang5fd7ba62019-11-28 15:58:08 +0800226 if (property.first !=
227 "MemorySizeInKB")
Ed Tanous6c34de42018-08-29 13:37:36 -0700228 {
Cheng C Yang5fd7ba62019-11-28 15:58:08 +0800229 continue;
Ed Tanous6c34de42018-08-29 13:37:36 -0700230 }
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500231 const uint32_t* value =
Patrick Williams8d78b7a2020-05-13 11:24:20 -0500232 std::get_if<uint32_t>(
233 &property.second);
Cheng C Yang5fd7ba62019-11-28 15:58:08 +0800234 if (value == nullptr)
235 {
236 BMCWEB_LOG_DEBUG
237 << "Find incorrect type of "
238 "MemorySize";
239 continue;
240 }
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500241 nlohmann::json& totalMemory =
Cheng C Yang5fd7ba62019-11-28 15:58:08 +0800242 aResp->res
243 .jsonValue["MemorySummar"
244 "y"]
245 ["TotalSystemMe"
246 "moryGiB"];
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500247 uint64_t* preValue =
Cheng C Yang5fd7ba62019-11-28 15:58:08 +0800248 totalMemory
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500249 .get_ptr<uint64_t*>();
Cheng C Yang5fd7ba62019-11-28 15:58:08 +0800250 if (preValue == nullptr)
251 {
252 continue;
253 }
254 aResp->res
255 .jsonValue["MemorySummary"]
256 ["TotalSystemMemoryGi"
257 "B"] =
258 *value / (1024 * 1024) +
259 *preValue;
260 aResp->res
261 .jsonValue["MemorySummary"]
262 ["Status"]["State"] =
263 "Enabled";
Ed Tanous6c34de42018-08-29 13:37:36 -0700264 }
Ed Tanous029573d2019-02-01 10:57:49 -0800265 }
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500266 else
267 {
268 auto getDimmProperties =
269 [aResp](
270 const boost::system::error_code
Ed Tanouscb13a392020-07-25 19:02:03 +0000271 ec3,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500272 const std::variant<bool>&
273 dimmState) {
Ed Tanouscb13a392020-07-25 19:02:03 +0000274 if (ec3)
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500275 {
276 BMCWEB_LOG_ERROR
277 << "DBUS response "
278 "error "
Ed Tanouscb13a392020-07-25 19:02:03 +0000279 << ec3;
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500280 return;
281 }
282 updateDimmProperties(aResp,
283 dimmState);
284 };
285 crow::connections::systemBus
286 ->async_method_call(
287 std::move(getDimmProperties),
288 service, path,
289 "org.freedesktop.DBus."
290 "Properties",
291 "Get",
292 "xyz.openbmc_project.State."
293 "Decorator.OperationalStatus",
294 "Functional");
295 }
Ed Tanous029573d2019-02-01 10:57:49 -0800296 },
297 connection.first, path,
298 "org.freedesktop.DBus.Properties", "GetAll",
299 "xyz.openbmc_project.Inventory.Item.Dimm");
James Feist5bc2dc82019-10-22 14:33:16 -0700300
301 memoryHealth->inventory.emplace_back(path);
Ed Tanous029573d2019-02-01 10:57:49 -0800302 }
303 else if (interfaceName ==
304 "xyz.openbmc_project.Inventory.Item.Cpu")
305 {
306 BMCWEB_LOG_DEBUG
307 << "Found Cpu, now get its properties.";
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500308
Ed Tanous029573d2019-02-01 10:57:49 -0800309 crow::connections::systemBus->async_method_call(
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500310 [aResp, service{connection.first},
311 path(std::move(path))](
Ed Tanouscb13a392020-07-25 19:02:03 +0000312 const boost::system::error_code ec2,
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500313 const std::vector<
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500314 std::pair<std::string, VariantType>>&
315 properties) {
Ed Tanouscb13a392020-07-25 19:02:03 +0000316 if (ec2)
Ed Tanous029573d2019-02-01 10:57:49 -0800317 {
318 BMCWEB_LOG_ERROR
Ed Tanouscb13a392020-07-25 19:02:03 +0000319 << "DBUS response error " << ec2;
Ed Tanous029573d2019-02-01 10:57:49 -0800320 messages::internalError(aResp->res);
321 return;
322 }
323 BMCWEB_LOG_DEBUG << "Got "
324 << properties.size()
Gunnar Mills698654b2019-10-16 13:17:37 -0500325 << " Cpu properties.";
Ed Tanous04a258f2018-10-15 08:00:41 -0700326
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500327 if (properties.size() > 0)
328 {
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700329 const uint32_t* processorId = nullptr;
330 const std::string* procFamily = nullptr;
331 nlohmann::json& procSummary =
332 aResp->res.jsonValue["ProcessorSumm"
333 "ary"];
334 nlohmann::json& procCount =
335 procSummary["Count"];
336
337 auto procCountPtr = procCount.get_ptr<
338 nlohmann::json::
339 number_integer_t*>();
340 if (procCountPtr == nullptr)
341 {
342 messages::internalError(aResp->res);
343 return;
344 }
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500345 for (const auto& property : properties)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500346 {
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700347
348 if (property.first == "ProcessorId")
349 {
350 processorId =
351 std::get_if<uint32_t>(
352 &property.second);
353 if (nullptr != procFamily)
354 break;
355 continue;
356 }
357
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500358 if (property.first ==
359 "ProcessorFamily")
360 {
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700361 procFamily =
Patrick Williams8d78b7a2020-05-13 11:24:20 -0500362 std::get_if<std::string>(
363 &property.second);
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700364 if (nullptr != processorId)
365 break;
366 continue;
367 }
368 }
James Feistb4b95952019-12-05 15:01:55 -0800369
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700370 if (procFamily != nullptr &&
371 processorId != nullptr)
372 {
373 if (procCountPtr != nullptr &&
374 *processorId != 0)
375 {
376 *procCountPtr += 1;
377 procSummary["Status"]["State"] =
378 "Enabled";
379
380 procSummary["Model"] =
381 *procFamily;
Ed Tanous6c34de42018-08-29 13:37:36 -0700382 }
383 }
Ed Tanous029573d2019-02-01 10:57:49 -0800384 }
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500385 else
386 {
387 auto getCpuPresenceState =
388 [aResp](
389 const boost::system::error_code
Ed Tanouscb13a392020-07-25 19:02:03 +0000390 ec3,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500391 const std::variant<bool>&
392 cpuPresenceCheck) {
Ed Tanouscb13a392020-07-25 19:02:03 +0000393 if (ec3)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500394 {
395 BMCWEB_LOG_ERROR
396 << "DBUS response "
397 "error "
Ed Tanouscb13a392020-07-25 19:02:03 +0000398 << ec3;
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500399 return;
400 }
401 modifyCpuPresenceState(
402 aResp, cpuPresenceCheck);
403 };
404
405 auto getCpuFunctionalState =
406 [aResp](
407 const boost::system::error_code
Ed Tanouscb13a392020-07-25 19:02:03 +0000408 ec3,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500409 const std::variant<bool>&
410 cpuFunctionalCheck) {
Ed Tanouscb13a392020-07-25 19:02:03 +0000411 if (ec3)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500412 {
413 BMCWEB_LOG_ERROR
414 << "DBUS response "
415 "error "
Ed Tanouscb13a392020-07-25 19:02:03 +0000416 << ec3;
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500417 return;
418 }
419 modifyCpuFunctionalState(
420 aResp, cpuFunctionalCheck);
421 };
422 // Get the Presence of CPU
423 crow::connections::systemBus
424 ->async_method_call(
425 std::move(getCpuPresenceState),
426 service, path,
427 "org.freedesktop.DBus."
428 "Properties",
429 "Get",
430 "xyz.openbmc_project.Inventory."
431 "Item",
432 "Present");
433
434 // Get the Functional State
435 crow::connections::systemBus
436 ->async_method_call(
437 std::move(
438 getCpuFunctionalState),
439 service, path,
440 "org.freedesktop.DBus."
441 "Properties",
442 "Get",
443 "xyz.openbmc_project.State."
444 "Decorator."
445 "OperationalStatus",
446 "Functional");
447
448 // Get the MODEL from
449 // xyz.openbmc_project.Inventory.Decorator.Asset
450 // support it later as Model is Empty
451 // currently.
452 }
Ed Tanous029573d2019-02-01 10:57:49 -0800453 },
454 connection.first, path,
455 "org.freedesktop.DBus.Properties", "GetAll",
456 "xyz.openbmc_project.Inventory.Item.Cpu");
James Feist5bc2dc82019-10-22 14:33:16 -0700457
458 cpuHealth->inventory.emplace_back(path);
Ed Tanous029573d2019-02-01 10:57:49 -0800459 }
460 else if (interfaceName ==
461 "xyz.openbmc_project.Common.UUID")
462 {
463 BMCWEB_LOG_DEBUG
464 << "Found UUID, now get its properties.";
465 crow::connections::systemBus->async_method_call(
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500466 [aResp](
Ed Tanouscb13a392020-07-25 19:02:03 +0000467 const boost::system::error_code ec3,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500468 const std::vector<
469 std::pair<std::string, VariantType>>&
470 properties) {
Ed Tanouscb13a392020-07-25 19:02:03 +0000471 if (ec3)
Ed Tanous029573d2019-02-01 10:57:49 -0800472 {
473 BMCWEB_LOG_DEBUG
Ed Tanouscb13a392020-07-25 19:02:03 +0000474 << "DBUS response error " << ec3;
Ed Tanous029573d2019-02-01 10:57:49 -0800475 messages::internalError(aResp->res);
476 return;
477 }
478 BMCWEB_LOG_DEBUG << "Got "
479 << properties.size()
Gunnar Mills698654b2019-10-16 13:17:37 -0500480 << " UUID properties.";
Ed Tanous029573d2019-02-01 10:57:49 -0800481 for (const std::pair<std::string,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500482 VariantType>&
483 property : properties)
Ed Tanous029573d2019-02-01 10:57:49 -0800484 {
Ed Tanous029573d2019-02-01 10:57:49 -0800485 if (property.first == "UUID")
486 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500487 const std::string* value =
Patrick Williams8d78b7a2020-05-13 11:24:20 -0500488 std::get_if<std::string>(
489 &property.second);
Ed Tanous04a258f2018-10-15 08:00:41 -0700490
Ed Tanous029573d2019-02-01 10:57:49 -0800491 if (value != nullptr)
492 {
493 std::string valueStr = *value;
494 if (valueStr.size() == 32)
Ed Tanous6c34de42018-08-29 13:37:36 -0700495 {
Ed Tanous029573d2019-02-01 10:57:49 -0800496 valueStr.insert(8, 1, '-');
497 valueStr.insert(13, 1, '-');
498 valueStr.insert(18, 1, '-');
499 valueStr.insert(23, 1, '-');
Ed Tanous6c34de42018-08-29 13:37:36 -0700500 }
Ed Tanous029573d2019-02-01 10:57:49 -0800501 BMCWEB_LOG_DEBUG << "UUID = "
502 << valueStr;
503 aResp->res.jsonValue["UUID"] =
504 valueStr;
Ed Tanous6c34de42018-08-29 13:37:36 -0700505 }
506 }
Ed Tanous029573d2019-02-01 10:57:49 -0800507 }
508 },
509 connection.first, path,
510 "org.freedesktop.DBus.Properties", "GetAll",
511 "xyz.openbmc_project.Common.UUID");
512 }
513 else if (interfaceName ==
514 "xyz.openbmc_project.Inventory.Item.System")
515 {
516 crow::connections::systemBus->async_method_call(
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500517 [aResp](
Ed Tanouscb13a392020-07-25 19:02:03 +0000518 const boost::system::error_code ec2,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500519 const std::vector<
520 std::pair<std::string, VariantType>>&
521 propertiesList) {
Ed Tanouscb13a392020-07-25 19:02:03 +0000522 if (ec2)
Ed Tanous029573d2019-02-01 10:57:49 -0800523 {
James Feiste4a4b9a2019-06-20 14:08:07 -0700524 // doesn't have to include this
525 // interface
Ed Tanous029573d2019-02-01 10:57:49 -0800526 return;
527 }
Gunnar Mills698654b2019-10-16 13:17:37 -0500528 BMCWEB_LOG_DEBUG
529 << "Got " << propertiesList.size()
530 << " properties for system";
Ed Tanous029573d2019-02-01 10:57:49 -0800531 for (const std::pair<std::string,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500532 VariantType>&
533 property : propertiesList)
Ed Tanous029573d2019-02-01 10:57:49 -0800534 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500535 const std::string& propertyName =
beccabroekfc5afcf2019-03-05 14:35:15 -0600536 property.first;
537 if ((propertyName == "PartNumber") ||
538 (propertyName == "SerialNumber") ||
539 (propertyName == "Manufacturer") ||
540 (propertyName == "Model"))
Ed Tanous029573d2019-02-01 10:57:49 -0800541 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500542 const std::string* value =
beccabroekfc5afcf2019-03-05 14:35:15 -0600543 std::get_if<std::string>(
544 &property.second);
545 if (value != nullptr)
546 {
547 aResp->res
548 .jsonValue[propertyName] =
549 *value;
550 }
Ed Tanous029573d2019-02-01 10:57:49 -0800551 }
552 }
Gunnar Millsc1e236a2020-04-14 21:36:33 -0500553
Andrew Geisslercb7e1e72019-02-19 13:05:38 -0600554 // Grab the bios version
Gunnar Millsf97ddba2020-08-20 15:57:40 -0500555 fw_util::populateFirmwareInformation(
Andrew Geisslercb7e1e72019-02-19 13:05:38 -0600556 aResp, fw_util::biosPurpose,
Gunnar Mills72d566d2020-07-21 12:44:00 -0500557 "BiosVersion", false);
Ed Tanous029573d2019-02-01 10:57:49 -0800558 },
559 connection.first, path,
560 "org.freedesktop.DBus.Properties", "GetAll",
561 "xyz.openbmc_project.Inventory.Decorator."
562 "Asset");
James Feiste4a4b9a2019-06-20 14:08:07 -0700563
564 crow::connections::systemBus->async_method_call(
565 [aResp](
Ed Tanouscb13a392020-07-25 19:02:03 +0000566 const boost::system::error_code ec2,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500567 const std::variant<std::string>& property) {
Ed Tanouscb13a392020-07-25 19:02:03 +0000568 if (ec2)
James Feiste4a4b9a2019-06-20 14:08:07 -0700569 {
570 // doesn't have to include this
571 // interface
572 return;
573 }
574
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500575 const std::string* value =
James Feiste4a4b9a2019-06-20 14:08:07 -0700576 std::get_if<std::string>(&property);
577 if (value != nullptr)
578 {
579 aResp->res.jsonValue["AssetTag"] =
580 *value;
581 }
582 },
583 connection.first, path,
584 "org.freedesktop.DBus.Properties", "Get",
585 "xyz.openbmc_project.Inventory.Decorator."
586 "AssetTag",
587 "AssetTag");
Ed Tanous6c34de42018-08-29 13:37:36 -0700588 }
589 }
590 }
591 }
Ed Tanous6c34de42018-08-29 13:37:36 -0700592 },
593 "xyz.openbmc_project.ObjectMapper",
594 "/xyz/openbmc_project/object_mapper",
595 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
Ed Tanous66173382018-08-15 18:20:59 -0700596 "/xyz/openbmc_project/inventory", int32_t(0),
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500597 std::array<const char*, 5>{
Ed Tanous66173382018-08-15 18:20:59 -0700598 "xyz.openbmc_project.Inventory.Decorator.Asset",
599 "xyz.openbmc_project.Inventory.Item.Cpu",
600 "xyz.openbmc_project.Inventory.Item.Dimm",
601 "xyz.openbmc_project.Inventory.Item.System",
602 "xyz.openbmc_project.Common.UUID",
603 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700604}
605
606/**
Ed Tanous6c34de42018-08-29 13:37:36 -0700607 * @brief Retrieves host state properties over dbus
608 *
609 * @param[in] aResp Shared pointer for completing asynchronous calls.
610 *
611 * @return None.
612 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000613inline void getHostState(std::shared_ptr<AsyncResp> aResp)
Ed Tanous6c34de42018-08-29 13:37:36 -0700614{
615 BMCWEB_LOG_DEBUG << "Get host information.";
616 crow::connections::systemBus->async_method_call(
Jennifer Leec5d03ff2019-03-08 15:42:58 -0800617 [aResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500618 const std::variant<std::string>& hostState) {
Ed Tanous6c34de42018-08-29 13:37:36 -0700619 if (ec)
620 {
621 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700622 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700623 return;
624 }
Ed Tanous66173382018-08-15 18:20:59 -0700625
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500626 const std::string* s = std::get_if<std::string>(&hostState);
Ed Tanous66173382018-08-15 18:20:59 -0700627 BMCWEB_LOG_DEBUG << "Host state: " << *s;
628 if (s != nullptr)
Ed Tanous6c34de42018-08-29 13:37:36 -0700629 {
Ed Tanous66173382018-08-15 18:20:59 -0700630 // Verify Host State
Andrew Geissler94732662019-01-08 19:32:16 -0800631 if (*s == "xyz.openbmc_project.State.Host.HostState.Running")
Ed Tanous6c34de42018-08-29 13:37:36 -0700632 {
Ed Tanous66173382018-08-15 18:20:59 -0700633 aResp->res.jsonValue["PowerState"] = "On";
634 aResp->res.jsonValue["Status"]["State"] = "Enabled";
635 }
Andrew Geissler83935af2020-02-13 10:24:53 -0600636 else if (*s == "xyz.openbmc_project.State.Host.HostState."
Gunnar Mills8c888602020-05-01 14:25:09 -0500637 "Quiesced")
638 {
639 aResp->res.jsonValue["PowerState"] = "On";
640 aResp->res.jsonValue["Status"]["State"] = "Quiesced";
641 }
642 else if (*s == "xyz.openbmc_project.State.Host.HostState."
Andrew Geissler83935af2020-02-13 10:24:53 -0600643 "DiagnosticMode")
644 {
645 aResp->res.jsonValue["PowerState"] = "On";
646 aResp->res.jsonValue["Status"]["State"] = "InTest";
647 }
Ed Tanous66173382018-08-15 18:20:59 -0700648 else
649 {
650 aResp->res.jsonValue["PowerState"] = "Off";
651 aResp->res.jsonValue["Status"]["State"] = "Disabled";
Ed Tanous6c34de42018-08-29 13:37:36 -0700652 }
653 }
654 },
655 "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
Ed Tanous66173382018-08-15 18:20:59 -0700656 "org.freedesktop.DBus.Properties", "Get",
657 "xyz.openbmc_project.State.Host", "CurrentHostState");
Ed Tanous6c34de42018-08-29 13:37:36 -0700658}
659
660/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500661 * @brief Translates boot source DBUS property value to redfish.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530662 *
663 * @param[in] dbusSource The boot source in DBUS speak.
664 *
665 * @return Returns as a string, the boot source in Redfish terms. If translation
666 * cannot be done, returns an empty string.
667 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000668inline std::string dbusToRfBootSource(const std::string& dbusSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530669{
670 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
671 {
672 return "None";
673 }
674 else if (dbusSource ==
675 "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
676 {
677 return "Hdd";
678 }
679 else if (dbusSource ==
Santosh Puranika71dc0b2019-05-23 20:10:49 +0530680 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530681 {
682 return "Cd";
683 }
684 else if (dbusSource ==
685 "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
686 {
687 return "Pxe";
688 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700689 else if (dbusSource ==
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700690 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700691 {
692 return "Usb";
693 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530694 else
695 {
696 return "";
697 }
698}
699
700/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500701 * @brief Translates boot mode DBUS property value to redfish.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530702 *
703 * @param[in] dbusMode The boot mode in DBUS speak.
704 *
705 * @return Returns as a string, the boot mode in Redfish terms. If translation
706 * cannot be done, returns an empty string.
707 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000708inline std::string dbusToRfBootMode(const std::string& dbusMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530709{
710 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
711 {
712 return "None";
713 }
714 else if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
715 {
716 return "Diags";
717 }
718 else if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
719 {
720 return "BiosSetup";
721 }
722 else
723 {
724 return "";
725 }
726}
727
728/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500729 * @brief Translates boot source from Redfish to the DBus boot paths.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530730 *
731 * @param[in] rfSource The boot source in Redfish.
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700732 * @param[out] bootSource The DBus source
733 * @param[out] bootMode the DBus boot mode
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530734 *
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700735 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530736 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000737inline int assignBootParameters(std::shared_ptr<AsyncResp> aResp,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500738 const std::string& rfSource,
739 std::string& bootSource, std::string& bootMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530740{
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700741 // The caller has initialized the bootSource and bootMode to:
742 // bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
743 // bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
744 // Only modify the bootSource/bootMode variable needed to achieve the
745 // desired boot action.
746
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530747 if (rfSource == "None")
748 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700749 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530750 }
751 else if (rfSource == "Pxe")
752 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700753 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
754 }
755 else if (rfSource == "Hdd")
756 {
757 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
758 }
759 else if (rfSource == "Diags")
760 {
761 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
762 }
763 else if (rfSource == "Cd")
764 {
765 bootSource =
766 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
767 }
768 else if (rfSource == "BiosSetup")
769 {
770 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530771 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700772 else if (rfSource == "Usb")
773 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700774 bootSource =
775 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700776 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530777 else
778 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700779 BMCWEB_LOG_DEBUG << "Invalid property value for "
780 "BootSourceOverrideTarget: "
781 << bootSource;
782 messages::propertyValueNotInList(aResp->res, rfSource,
783 "BootSourceTargetOverride");
784 return -1;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530785 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700786 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530787}
788
789/**
790 * @brief Retrieves boot mode over DBUS and fills out the response
791 *
792 * @param[in] aResp Shared pointer for generating response message.
793 * @param[in] bootDbusObj The dbus object to query for boot properties.
794 *
795 * @return None.
796 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000797inline void getBootMode(std::shared_ptr<AsyncResp> aResp,
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530798 std::string bootDbusObj)
799{
800 crow::connections::systemBus->async_method_call(
801 [aResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500802 const std::variant<std::string>& bootMode) {
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530803 if (ec)
804 {
805 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
806 messages::internalError(aResp->res);
807 return;
808 }
809
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500810 const std::string* bootModeStr =
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530811 std::get_if<std::string>(&bootMode);
812
813 if (!bootModeStr)
814 {
815 messages::internalError(aResp->res);
816 return;
817 }
818
819 BMCWEB_LOG_DEBUG << "Boot mode: " << *bootModeStr;
820
821 // TODO (Santosh): Do we need to support override mode?
822 aResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = "Legacy";
823 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget@Redfish."
824 "AllowableValues"] = {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700825 "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530826
827 if (*bootModeStr !=
828 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
829 {
830 auto rfMode = dbusToRfBootMode(*bootModeStr);
831 if (!rfMode.empty())
832 {
833 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
834 rfMode;
835 }
836 }
837
838 // If the BootSourceOverrideTarget is still "None" at the end,
839 // reset the BootSourceOverrideEnabled to indicate that
840 // overrides are disabled
841 if (aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] ==
842 "None")
843 {
844 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
845 "Disabled";
846 }
847 },
848 "xyz.openbmc_project.Settings", bootDbusObj,
849 "org.freedesktop.DBus.Properties", "Get",
850 "xyz.openbmc_project.Control.Boot.Mode", "BootMode");
851}
852
853/**
854 * @brief Retrieves boot source over DBUS
855 *
856 * @param[in] aResp Shared pointer for generating response message.
857 * @param[in] oneTimeEnable Boolean to indicate boot properties are one-time.
858 *
859 * @return None.
860 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000861inline void getBootSource(std::shared_ptr<AsyncResp> aResp, bool oneTimeEnabled)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530862{
863 std::string bootDbusObj =
864 oneTimeEnabled ? "/xyz/openbmc_project/control/host0/boot/one_time"
865 : "/xyz/openbmc_project/control/host0/boot";
866
867 BMCWEB_LOG_DEBUG << "Is one time: " << oneTimeEnabled;
868 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
869 (oneTimeEnabled) ? "Once" : "Continuous";
870
871 crow::connections::systemBus->async_method_call(
872 [aResp, bootDbusObj](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500873 const std::variant<std::string>& bootSource) {
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530874 if (ec)
875 {
876 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
877 messages::internalError(aResp->res);
878 return;
879 }
880
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500881 const std::string* bootSourceStr =
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530882 std::get_if<std::string>(&bootSource);
883
884 if (!bootSourceStr)
885 {
886 messages::internalError(aResp->res);
887 return;
888 }
889 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSourceStr;
890
891 auto rfSource = dbusToRfBootSource(*bootSourceStr);
892 if (!rfSource.empty())
893 {
894 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
895 rfSource;
896 }
897 },
898 "xyz.openbmc_project.Settings", bootDbusObj,
899 "org.freedesktop.DBus.Properties", "Get",
900 "xyz.openbmc_project.Control.Boot.Source", "BootSource");
901 getBootMode(std::move(aResp), std::move(bootDbusObj));
902}
903
904/**
905 * @brief Retrieves "One time" enabled setting over DBUS and calls function to
906 * get boot source and boot mode.
907 *
908 * @param[in] aResp Shared pointer for generating response message.
909 *
910 * @return None.
911 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000912inline void getBootProperties(std::shared_ptr<AsyncResp> aResp)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530913{
914 BMCWEB_LOG_DEBUG << "Get boot information.";
915
916 crow::connections::systemBus->async_method_call(
Jennifer Leec5d03ff2019-03-08 15:42:58 -0800917 [aResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500918 const std::variant<bool>& oneTime) {
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530919 if (ec)
920 {
921 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
James Feist2a833c72019-07-19 10:17:13 -0700922 // not an error, don't have to have the interface
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530923 return;
924 }
925
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500926 const bool* oneTimePtr = std::get_if<bool>(&oneTime);
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530927
928 if (!oneTimePtr)
929 {
930 messages::internalError(aResp->res);
931 return;
932 }
933 getBootSource(aResp, *oneTimePtr);
934 },
935 "xyz.openbmc_project.Settings",
936 "/xyz/openbmc_project/control/host0/boot/one_time",
937 "org.freedesktop.DBus.Properties", "Get",
938 "xyz.openbmc_project.Object.Enable", "Enabled");
939}
940
941/**
Gunnar Millsc0557e12020-06-30 11:26:20 -0500942 * @brief Retrieves the Last Reset Time
943 *
944 * "Reset" is an overloaded term in Redfish, "Reset" includes power on
945 * and power off. Even though this is the "system" Redfish object look at the
946 * chassis D-Bus interface for the LastStateChangeTime since this has the
947 * last power operation time.
948 *
949 * @param[in] aResp Shared pointer for generating response message.
950 *
951 * @return None.
952 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000953inline void getLastResetTime(std::shared_ptr<AsyncResp> aResp)
Gunnar Millsc0557e12020-06-30 11:26:20 -0500954{
955 BMCWEB_LOG_DEBUG << "Getting System Last Reset Time";
956
957 crow::connections::systemBus->async_method_call(
958 [aResp](const boost::system::error_code ec,
959 std::variant<uint64_t>& lastResetTime) {
960 if (ec)
961 {
962 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
963 return;
964 }
965
966 const uint64_t* lastResetTimePtr =
967 std::get_if<uint64_t>(&lastResetTime);
968
969 if (!lastResetTimePtr)
970 {
971 messages::internalError(aResp->res);
972 return;
973 }
974 // LastStateChangeTime is epoch time, in milliseconds
975 // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
976 time_t lastResetTimeStamp =
977 static_cast<time_t>(*lastResetTimePtr / 1000);
978
979 // Convert to ISO 8601 standard
980 aResp->res.jsonValue["LastResetTime"] =
981 crow::utility::getDateTime(lastResetTimeStamp);
982 },
983 "xyz.openbmc_project.State.Chassis",
984 "/xyz/openbmc_project/state/chassis0",
985 "org.freedesktop.DBus.Properties", "Get",
986 "xyz.openbmc_project.State.Chassis", "LastStateChangeTime");
987}
988
989/**
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -0500990 * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
991 *
992 * @param[in] aResp Shared pointer for generating response message.
993 *
994 * @return None.
995 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000996inline void getAutomaticRetry(std::shared_ptr<AsyncResp> aResp)
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -0500997{
998 BMCWEB_LOG_DEBUG << "Get Automatic Retry policy";
999
1000 crow::connections::systemBus->async_method_call(
1001 [aResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001002 std::variant<bool>& autoRebootEnabled) {
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001003 if (ec)
1004 {
1005 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
1006 return;
1007 }
1008
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001009 const bool* autoRebootEnabledPtr =
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001010 std::get_if<bool>(&autoRebootEnabled);
1011
1012 if (!autoRebootEnabledPtr)
1013 {
1014 messages::internalError(aResp->res);
1015 return;
1016 }
1017
1018 BMCWEB_LOG_DEBUG << "Auto Reboot: " << *autoRebootEnabledPtr;
1019 if (*autoRebootEnabledPtr == true)
1020 {
1021 aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
1022 "RetryAttempts";
1023 // If AutomaticRetry (AutoReboot) is enabled see how many
1024 // attempts are left
1025 crow::connections::systemBus->async_method_call(
Ed Tanouscb13a392020-07-25 19:02:03 +00001026 [aResp](const boost::system::error_code ec2,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001027 std::variant<uint32_t>& autoRebootAttemptsLeft) {
Ed Tanouscb13a392020-07-25 19:02:03 +00001028 if (ec2)
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001029 {
Ed Tanouscb13a392020-07-25 19:02:03 +00001030 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec2;
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001031 return;
1032 }
1033
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001034 const uint32_t* autoRebootAttemptsLeftPtr =
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001035 std::get_if<uint32_t>(&autoRebootAttemptsLeft);
1036
1037 if (!autoRebootAttemptsLeftPtr)
1038 {
1039 messages::internalError(aResp->res);
1040 return;
1041 }
1042
1043 BMCWEB_LOG_DEBUG << "Auto Reboot Attempts Left: "
1044 << *autoRebootAttemptsLeftPtr;
1045
1046 aResp->res
1047 .jsonValue["Boot"]
1048 ["RemainingAutomaticRetryAttempts"] =
1049 *autoRebootAttemptsLeftPtr;
1050 },
1051 "xyz.openbmc_project.State.Host",
1052 "/xyz/openbmc_project/state/host0",
1053 "org.freedesktop.DBus.Properties", "Get",
1054 "xyz.openbmc_project.Control.Boot.RebootAttempts",
1055 "AttemptsLeft");
1056 }
1057 else
1058 {
1059 aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
1060 "Disabled";
1061 }
1062
1063 // Not on D-Bus. Hardcoded here:
1064 // https://github.com/openbmc/phosphor-state-manager/blob/1dbbef42675e94fb1f78edb87d6b11380260535a/meson_options.txt#L71
1065 aResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] = 3;
Gunnar Mills69f35302020-05-17 16:06:31 -05001066
1067 // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
1068 // and RetryAttempts. OpenBMC only supports Disabled and
1069 // RetryAttempts.
1070 aResp->res.jsonValue["Boot"]["AutomaticRetryConfig@Redfish."
1071 "AllowableValues"] = {"Disabled",
1072 "RetryAttempts"};
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001073 },
1074 "xyz.openbmc_project.Settings",
1075 "/xyz/openbmc_project/control/host0/auto_reboot",
1076 "org.freedesktop.DBus.Properties", "Get",
1077 "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot");
1078}
1079
1080/**
George Liuc6a620f2020-04-10 17:18:11 +08001081 * @brief Retrieves power restore policy over DBUS.
1082 *
1083 * @param[in] aResp Shared pointer for generating response message.
1084 *
1085 * @return None.
1086 */
Ed Tanous23a21a12020-07-25 04:45:05 +00001087inline void getPowerRestorePolicy(std::shared_ptr<AsyncResp> aResp)
George Liuc6a620f2020-04-10 17:18:11 +08001088{
1089 BMCWEB_LOG_DEBUG << "Get power restore policy";
1090
1091 crow::connections::systemBus->async_method_call(
1092 [aResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001093 std::variant<std::string>& policy) {
George Liuc6a620f2020-04-10 17:18:11 +08001094 if (ec)
1095 {
1096 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1097 return;
1098 }
1099
1100 const boost::container::flat_map<std::string, std::string>
1101 policyMaps = {
1102 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1103 "AlwaysOn",
1104 "AlwaysOn"},
1105 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1106 "AlwaysOff",
1107 "AlwaysOff"},
1108 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1109 "LastState",
1110 "LastState"}};
1111
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001112 const std::string* policyPtr = std::get_if<std::string>(&policy);
George Liuc6a620f2020-04-10 17:18:11 +08001113
1114 if (!policyPtr)
1115 {
1116 messages::internalError(aResp->res);
1117 return;
1118 }
1119
1120 auto policyMapsIt = policyMaps.find(*policyPtr);
1121 if (policyMapsIt == policyMaps.end())
1122 {
1123 messages::internalError(aResp->res);
1124 return;
1125 }
1126
1127 aResp->res.jsonValue["PowerRestorePolicy"] = policyMapsIt->second;
1128 },
1129 "xyz.openbmc_project.Settings",
1130 "/xyz/openbmc_project/control/host0/power_restore_policy",
1131 "org.freedesktop.DBus.Properties", "Get",
1132 "xyz.openbmc_project.Control.Power.RestorePolicy",
1133 "PowerRestorePolicy");
1134}
1135
1136/**
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301137 * @brief Sets boot properties into DBUS object(s).
1138 *
1139 * @param[in] aResp Shared pointer for generating response message.
1140 * @param[in] oneTimeEnabled Is "one-time" setting already enabled.
1141 * @param[in] bootSource The boot source to set.
1142 * @param[in] bootEnable The source override "enable" to set.
1143 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001144 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301145 */
Ed Tanous23a21a12020-07-25 04:45:05 +00001146inline void setBootModeOrSource(std::shared_ptr<AsyncResp> aResp,
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301147 bool oneTimeEnabled,
1148 std::optional<std::string> bootSource,
1149 std::optional<std::string> bootEnable)
1150{
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001151 std::string bootSourceStr =
1152 "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
1153 std::string bootModeStr =
1154 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301155 bool oneTimeSetting = oneTimeEnabled;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001156 bool useBootSource = true;
1157
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301158 // Validate incoming parameters
1159 if (bootEnable)
1160 {
1161 if (*bootEnable == "Once")
1162 {
1163 oneTimeSetting = true;
1164 }
1165 else if (*bootEnable == "Continuous")
1166 {
1167 oneTimeSetting = false;
1168 }
1169 else if (*bootEnable == "Disabled")
1170 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001171 BMCWEB_LOG_DEBUG << "Boot source override will be disabled";
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301172 oneTimeSetting = false;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001173 useBootSource = false;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301174 }
1175 else
1176 {
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301177 BMCWEB_LOG_DEBUG << "Unsupported value for "
1178 "BootSourceOverrideEnabled: "
1179 << *bootEnable;
1180 messages::propertyValueNotInList(aResp->res, *bootEnable,
1181 "BootSourceOverrideEnabled");
1182 return;
1183 }
1184 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301185
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001186 if (bootSource && useBootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301187 {
1188 // Source target specified
1189 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource;
1190 // Figure out which DBUS interface and property to use
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001191 if (assignBootParameters(aResp, *bootSource, bootSourceStr,
1192 bootModeStr))
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301193 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001194 BMCWEB_LOG_DEBUG
1195 << "Invalid property value for BootSourceOverrideTarget: "
1196 << *bootSource;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301197 messages::propertyValueNotInList(aResp->res, *bootSource,
1198 "BootSourceTargetOverride");
1199 return;
1200 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001201 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301202
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001203 // Act on validated parameters
1204 BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
1205 BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001206 const char* bootObj =
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001207 oneTimeSetting ? "/xyz/openbmc_project/control/host0/boot/one_time"
1208 : "/xyz/openbmc_project/control/host0/boot";
1209
1210 crow::connections::systemBus->async_method_call(
1211 [aResp](const boost::system::error_code ec) {
1212 if (ec)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301213 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001214 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1215 messages::internalError(aResp->res);
1216 return;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301217 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001218 BMCWEB_LOG_DEBUG << "Boot source update done.";
1219 },
1220 "xyz.openbmc_project.Settings", bootObj,
1221 "org.freedesktop.DBus.Properties", "Set",
1222 "xyz.openbmc_project.Control.Boot.Source", "BootSource",
1223 std::variant<std::string>(bootSourceStr));
1224
1225 crow::connections::systemBus->async_method_call(
1226 [aResp](const boost::system::error_code ec) {
1227 if (ec)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301228 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001229 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1230 messages::internalError(aResp->res);
1231 return;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301232 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001233 BMCWEB_LOG_DEBUG << "Boot mode update done.";
1234 },
1235 "xyz.openbmc_project.Settings", bootObj,
1236 "org.freedesktop.DBus.Properties", "Set",
1237 "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
1238 std::variant<std::string>(bootModeStr));
1239
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301240 crow::connections::systemBus->async_method_call(
1241 [aResp{std::move(aResp)}](const boost::system::error_code ec) {
1242 if (ec)
1243 {
1244 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1245 messages::internalError(aResp->res);
1246 return;
1247 }
1248 BMCWEB_LOG_DEBUG << "Boot enable update done.";
1249 },
1250 "xyz.openbmc_project.Settings",
1251 "/xyz/openbmc_project/control/host0/boot/one_time",
1252 "org.freedesktop.DBus.Properties", "Set",
1253 "xyz.openbmc_project.Object.Enable", "Enabled",
1254 std::variant<bool>(oneTimeSetting));
1255}
1256
1257/**
1258 * @brief Retrieves "One time" enabled setting over DBUS and calls function to
1259 * set boot source/boot mode properties.
1260 *
1261 * @param[in] aResp Shared pointer for generating response message.
1262 * @param[in] bootSource The boot source from incoming RF request.
1263 * @param[in] bootEnable The boot override enable from incoming RF request.
1264 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001265 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301266 */
Ed Tanous23a21a12020-07-25 04:45:05 +00001267inline void setBootSourceProperties(std::shared_ptr<AsyncResp> aResp,
Gunnar Mills69f35302020-05-17 16:06:31 -05001268 std::optional<std::string> bootSource,
1269 std::optional<std::string> bootEnable)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301270{
1271 BMCWEB_LOG_DEBUG << "Set boot information.";
1272
1273 crow::connections::systemBus->async_method_call(
Johnathan Mantey265c1602019-08-08 11:02:51 -07001274 [aResp, bootSource{std::move(bootSource)},
Patrick Williams19bd78d2020-05-13 17:38:24 -05001275 bootEnable{std::move(bootEnable)}](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001276 const std::variant<bool>& oneTime) {
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301277 if (ec)
1278 {
1279 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1280 messages::internalError(aResp->res);
1281 return;
1282 }
1283
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001284 const bool* oneTimePtr = std::get_if<bool>(&oneTime);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301285
1286 if (!oneTimePtr)
1287 {
1288 messages::internalError(aResp->res);
1289 return;
1290 }
1291
1292 BMCWEB_LOG_DEBUG << "Got one time: " << *oneTimePtr;
1293
1294 setBootModeOrSource(aResp, *oneTimePtr, std::move(bootSource),
1295 std::move(bootEnable));
1296 },
1297 "xyz.openbmc_project.Settings",
1298 "/xyz/openbmc_project/control/host0/boot/one_time",
1299 "org.freedesktop.DBus.Properties", "Get",
1300 "xyz.openbmc_project.Object.Enable", "Enabled");
1301}
1302
George Liuc6a620f2020-04-10 17:18:11 +08001303/**
Gunnar Mills69f35302020-05-17 16:06:31 -05001304 * @brief Sets automaticRetry (Auto Reboot)
1305 *
1306 * @param[in] aResp Shared pointer for generating response message.
1307 * @param[in] automaticRetryConfig "AutomaticRetryConfig" from request.
1308 *
1309 * @return None.
1310 */
Ed Tanous23a21a12020-07-25 04:45:05 +00001311inline void setAutomaticRetry(std::shared_ptr<AsyncResp> aResp,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001312 const std::string&& automaticRetryConfig)
Gunnar Mills69f35302020-05-17 16:06:31 -05001313{
1314 BMCWEB_LOG_DEBUG << "Set Automatic Retry.";
1315
1316 // OpenBMC only supports "Disabled" and "RetryAttempts".
1317 bool autoRebootEnabled;
1318
1319 if (automaticRetryConfig == "Disabled")
1320 {
1321 autoRebootEnabled = false;
1322 }
1323 else if (automaticRetryConfig == "RetryAttempts")
1324 {
1325 autoRebootEnabled = true;
1326 }
1327 else
1328 {
1329 BMCWEB_LOG_DEBUG << "Invalid property value for "
1330 "AutomaticRetryConfig: "
1331 << automaticRetryConfig;
1332 messages::propertyValueNotInList(aResp->res, automaticRetryConfig,
1333 "AutomaticRetryConfig");
1334 return;
1335 }
1336
1337 crow::connections::systemBus->async_method_call(
1338 [aResp](const boost::system::error_code ec) {
1339 if (ec)
1340 {
1341 messages::internalError(aResp->res);
1342 return;
1343 }
1344 },
1345 "xyz.openbmc_project.Settings",
1346 "/xyz/openbmc_project/control/host0/auto_reboot",
1347 "org.freedesktop.DBus.Properties", "Set",
1348 "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
1349 std::variant<bool>(autoRebootEnabled));
1350}
1351
1352/**
George Liuc6a620f2020-04-10 17:18:11 +08001353 * @brief Sets power restore policy properties.
1354 *
1355 * @param[in] aResp Shared pointer for generating response message.
1356 * @param[in] policy power restore policy properties from request.
1357 *
1358 * @return None.
1359 */
Ed Tanous23a21a12020-07-25 04:45:05 +00001360inline void setPowerRestorePolicy(std::shared_ptr<AsyncResp> aResp,
George Liuc6a620f2020-04-10 17:18:11 +08001361 std::optional<std::string> policy)
1362{
1363 BMCWEB_LOG_DEBUG << "Set power restore policy.";
1364
1365 const boost::container::flat_map<std::string, std::string> policyMaps = {
1366 {"AlwaysOn", "xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1367 "AlwaysOn"},
1368 {"AlwaysOff", "xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1369 "AlwaysOff"},
1370 {"LastState", "xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1371 "LastState"}};
1372
1373 std::string powerRestorPolicy;
1374
1375 auto policyMapsIt = policyMaps.find(*policy);
1376 if (policyMapsIt == policyMaps.end())
1377 {
1378 messages::internalError(aResp->res);
1379 return;
1380 }
1381
1382 powerRestorPolicy = policyMapsIt->second;
1383
1384 crow::connections::systemBus->async_method_call(
1385 [aResp](const boost::system::error_code ec) {
1386 if (ec)
1387 {
1388 messages::internalError(aResp->res);
1389 return;
1390 }
1391 },
1392 "xyz.openbmc_project.Settings",
1393 "/xyz/openbmc_project/control/host0/power_restore_policy",
1394 "org.freedesktop.DBus.Properties", "Set",
1395 "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
1396 std::variant<std::string>(powerRestorPolicy));
1397}
1398
AppaRao Pulia6349912019-10-18 17:16:08 +05301399#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1400/**
1401 * @brief Retrieves provisioning status
1402 *
1403 * @param[in] aResp Shared pointer for completing asynchronous calls.
1404 *
1405 * @return None.
1406 */
Ed Tanous23a21a12020-07-25 04:45:05 +00001407inline void getProvisioningStatus(std::shared_ptr<AsyncResp> aResp)
AppaRao Pulia6349912019-10-18 17:16:08 +05301408{
1409 BMCWEB_LOG_DEBUG << "Get OEM information.";
1410 crow::connections::systemBus->async_method_call(
1411 [aResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001412 const std::vector<std::pair<std::string, VariantType>>&
1413 propertiesList) {
AppaRao Pulib99fb1a2020-07-08 16:42:48 +05301414 nlohmann::json& oemPFR =
1415 aResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
AppaRao Pulia6349912019-10-18 17:16:08 +05301416 if (ec)
1417 {
1418 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
AppaRao Pulib99fb1a2020-07-08 16:42:48 +05301419 // not an error, don't have to have the interface
1420 oemPFR["ProvisioningStatus"] = "NotProvisioned";
AppaRao Pulia6349912019-10-18 17:16:08 +05301421 return;
1422 }
1423
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001424 const bool* provState = nullptr;
1425 const bool* lockState = nullptr;
1426 for (const std::pair<std::string, VariantType>& property :
AppaRao Pulia6349912019-10-18 17:16:08 +05301427 propertiesList)
1428 {
1429 if (property.first == "UfmProvisioned")
1430 {
1431 provState = std::get_if<bool>(&property.second);
1432 }
1433 else if (property.first == "UfmLocked")
1434 {
1435 lockState = std::get_if<bool>(&property.second);
1436 }
1437 }
1438
1439 if ((provState == nullptr) || (lockState == nullptr))
1440 {
1441 BMCWEB_LOG_DEBUG << "Unable to get PFR attributes.";
1442 messages::internalError(aResp->res);
1443 return;
1444 }
1445
AppaRao Pulia6349912019-10-18 17:16:08 +05301446 if (*provState == true)
1447 {
1448 if (*lockState == true)
1449 {
1450 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
1451 }
1452 else
1453 {
1454 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
1455 }
1456 }
1457 else
1458 {
1459 oemPFR["ProvisioningStatus"] = "NotProvisioned";
1460 }
1461 },
1462 "xyz.openbmc_project.PFR.Manager", "/xyz/openbmc_project/pfr",
1463 "org.freedesktop.DBus.Properties", "GetAll",
1464 "xyz.openbmc_project.PFR.Attributes");
1465}
1466#endif
1467
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301468/**
Yong Li51709ff2019-09-30 14:13:04 +08001469 * @brief Translates watchdog timeout action DBUS property value to redfish.
1470 *
1471 * @param[in] dbusAction The watchdog timeout action in D-BUS.
1472 *
1473 * @return Returns as a string, the timeout action in Redfish terms. If
1474 * translation cannot be done, returns an empty string.
1475 */
Ed Tanous23a21a12020-07-25 04:45:05 +00001476inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
Yong Li51709ff2019-09-30 14:13:04 +08001477{
1478 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
1479 {
1480 return "None";
1481 }
1482 else if (dbusAction ==
1483 "xyz.openbmc_project.State.Watchdog.Action.HardReset")
1484 {
1485 return "ResetSystem";
1486 }
1487 else if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
1488 {
1489 return "PowerDown";
1490 }
1491 else if (dbusAction ==
1492 "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
1493 {
1494 return "PowerCycle";
1495 }
1496
1497 return "";
1498}
1499
1500/**
Yong Lic45f0082019-10-10 14:19:01 +08001501 *@brief Translates timeout action from Redfish to DBUS property value.
1502 *
1503 *@param[in] rfAction The timeout action in Redfish.
1504 *
1505 *@return Returns as a string, the time_out action as expected by DBUS.
1506 *If translation cannot be done, returns an empty string.
1507 */
1508
Ed Tanous23a21a12020-07-25 04:45:05 +00001509inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
Yong Lic45f0082019-10-10 14:19:01 +08001510{
1511 if (rfAction == "None")
1512 {
1513 return "xyz.openbmc_project.State.Watchdog.Action.None";
1514 }
1515 else if (rfAction == "PowerCycle")
1516 {
1517 return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
1518 }
1519 else if (rfAction == "PowerDown")
1520 {
1521 return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
1522 }
1523 else if (rfAction == "ResetSystem")
1524 {
1525 return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
1526 }
1527
1528 return "";
1529}
1530
1531/**
Yong Li51709ff2019-09-30 14:13:04 +08001532 * @brief Retrieves host watchdog timer properties over DBUS
1533 *
1534 * @param[in] aResp Shared pointer for completing asynchronous calls.
1535 *
1536 * @return None.
1537 */
Ed Tanous23a21a12020-07-25 04:45:05 +00001538inline void getHostWatchdogTimer(std::shared_ptr<AsyncResp> aResp)
Yong Li51709ff2019-09-30 14:13:04 +08001539{
1540 BMCWEB_LOG_DEBUG << "Get host watchodg";
1541 crow::connections::systemBus->async_method_call(
1542 [aResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001543 PropertiesType& properties) {
Yong Li51709ff2019-09-30 14:13:04 +08001544 if (ec)
1545 {
1546 // watchdog service is stopped
1547 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1548 return;
1549 }
1550
1551 BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop.";
1552
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001553 nlohmann::json& hostWatchdogTimer =
Yong Li51709ff2019-09-30 14:13:04 +08001554 aResp->res.jsonValue["HostWatchdogTimer"];
1555
1556 // watchdog service is running/enabled
1557 hostWatchdogTimer["Status"]["State"] = "Enabled";
1558
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001559 for (const auto& property : properties)
Yong Li51709ff2019-09-30 14:13:04 +08001560 {
1561 BMCWEB_LOG_DEBUG << "prop=" << property.first;
1562 if (property.first == "Enabled")
1563 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001564 const bool* state = std::get_if<bool>(&property.second);
Yong Li51709ff2019-09-30 14:13:04 +08001565
1566 if (!state)
1567 {
1568 messages::internalError(aResp->res);
1569 continue;
1570 }
1571
1572 hostWatchdogTimer["FunctionEnabled"] = *state;
1573 }
1574 else if (property.first == "ExpireAction")
1575 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001576 const std::string* s =
Yong Li51709ff2019-09-30 14:13:04 +08001577 std::get_if<std::string>(&property.second);
1578 if (!s)
1579 {
1580 messages::internalError(aResp->res);
1581 continue;
1582 }
1583
1584 std::string action = dbusToRfWatchdogAction(*s);
1585 if (action.empty())
1586 {
1587 messages::internalError(aResp->res);
1588 continue;
1589 }
1590 hostWatchdogTimer["TimeoutAction"] = action;
1591 }
1592 }
1593 },
1594 "xyz.openbmc_project.Watchdog", "/xyz/openbmc_project/watchdog/host0",
1595 "org.freedesktop.DBus.Properties", "GetAll",
1596 "xyz.openbmc_project.State.Watchdog");
1597}
1598
1599/**
Yong Lic45f0082019-10-10 14:19:01 +08001600 * @brief Sets Host WatchDog Timer properties.
1601 *
1602 * @param[in] aResp Shared pointer for generating response message.
1603 * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming
1604 * RF request.
1605 * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
1606 *
1607 * @return None.
1608 */
Ed Tanous23a21a12020-07-25 04:45:05 +00001609inline void setWDTProperties(std::shared_ptr<AsyncResp> aResp,
Yong Lic45f0082019-10-10 14:19:01 +08001610 const std::optional<bool> wdtEnable,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001611 const std::optional<std::string>& wdtTimeOutAction)
Yong Lic45f0082019-10-10 14:19:01 +08001612{
1613 BMCWEB_LOG_DEBUG << "Set host watchdog";
1614
1615 if (wdtTimeOutAction)
1616 {
1617 std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
1618 // check if TimeOut Action is Valid
1619 if (wdtTimeOutActStr.empty())
1620 {
1621 BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: "
1622 << *wdtTimeOutAction;
1623 messages::propertyValueNotInList(aResp->res, *wdtTimeOutAction,
1624 "TimeoutAction");
1625 return;
1626 }
1627
1628 crow::connections::systemBus->async_method_call(
1629 [aResp](const boost::system::error_code ec) {
1630 if (ec)
1631 {
1632 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1633 messages::internalError(aResp->res);
1634 return;
1635 }
1636 },
1637 "xyz.openbmc_project.Watchdog",
1638 "/xyz/openbmc_project/watchdog/host0",
1639 "org.freedesktop.DBus.Properties", "Set",
1640 "xyz.openbmc_project.State.Watchdog", "ExpireAction",
1641 std::variant<std::string>(wdtTimeOutActStr));
1642 }
1643
1644 if (wdtEnable)
1645 {
1646 crow::connections::systemBus->async_method_call(
1647 [aResp](const boost::system::error_code ec) {
1648 if (ec)
1649 {
1650 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1651 messages::internalError(aResp->res);
1652 return;
1653 }
1654 },
1655 "xyz.openbmc_project.Watchdog",
1656 "/xyz/openbmc_project/watchdog/host0",
1657 "org.freedesktop.DBus.Properties", "Set",
1658 "xyz.openbmc_project.State.Watchdog", "Enabled",
1659 std::variant<bool>(*wdtEnable));
1660 }
1661}
1662
1663/**
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001664 * SystemsCollection derived class for delivering ComputerSystems Collection
1665 * Schema
1666 */
Ed Tanous1abe55e2018-09-05 08:30:59 -07001667class SystemsCollection : public Node
1668{
1669 public:
Ed Tanous52cc1122020-07-18 13:51:21 -07001670 SystemsCollection(App& app) : Node(app, "/redfish/v1/Systems/")
Ed Tanous1abe55e2018-09-05 08:30:59 -07001671 {
Ed Tanous1abe55e2018-09-05 08:30:59 -07001672 entityPrivileges = {
1673 {boost::beast::http::verb::get, {{"Login"}}},
1674 {boost::beast::http::verb::head, {{"Login"}}},
1675 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1676 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1677 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1678 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1679 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001680
Ed Tanous1abe55e2018-09-05 08:30:59 -07001681 private:
Ed Tanouscb13a392020-07-25 19:02:03 +00001682 void doGet(crow::Response& res, const crow::Request&,
1683 const std::vector<std::string>&) override
Ed Tanous1abe55e2018-09-05 08:30:59 -07001684 {
Sunitha Harish462023a2020-02-19 08:34:59 -06001685 std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
Ed Tanous0f74e642018-11-12 15:17:05 -08001686 res.jsonValue["@odata.type"] =
1687 "#ComputerSystemCollection.ComputerSystemCollection";
1688 res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
Ed Tanous0f74e642018-11-12 15:17:05 -08001689 res.jsonValue["Name"] = "Computer System Collection";
Sunitha Harish462023a2020-02-19 08:34:59 -06001690
1691 crow::connections::systemBus->async_method_call(
1692 [asyncResp](const boost::system::error_code ec,
Ed Tanouscb13a392020-07-25 19:02:03 +00001693 const std::variant<std::string>& /*hostName*/) {
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001694 nlohmann::json& iface_array =
Sunitha Harish462023a2020-02-19 08:34:59 -06001695 asyncResp->res.jsonValue["Members"];
1696 iface_array = nlohmann::json::array();
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001697 auto& count = asyncResp->res.jsonValue["Members@odata.count"];
Sunitha Harish462023a2020-02-19 08:34:59 -06001698 count = 0;
Ed Tanouscb13a392020-07-25 19:02:03 +00001699 iface_array.push_back(
1700 {{"@odata.id", "/redfish/v1/Systems/system"}});
1701 if (!ec)
Sunitha Harish462023a2020-02-19 08:34:59 -06001702 {
Ed Tanouscb13a392020-07-25 19:02:03 +00001703 BMCWEB_LOG_DEBUG << "Hypervisor is available";
Sunitha Harish462023a2020-02-19 08:34:59 -06001704 iface_array.push_back(
Ed Tanouscb13a392020-07-25 19:02:03 +00001705 {{"@odata.id", "/redfish/v1/Systems/hypervisor"}});
Sunitha Harish462023a2020-02-19 08:34:59 -06001706 count = iface_array.size();
1707 return;
1708 }
Sunitha Harish462023a2020-02-19 08:34:59 -06001709 },
Sunitha Harish8e651fb2020-06-17 06:06:25 -05001710 "xyz.openbmc_project.Settings",
1711 "/xyz/openbmc_project/network/hypervisor",
Sunitha Harish462023a2020-02-19 08:34:59 -06001712 "org.freedesktop.DBus.Properties", "Get",
1713 "xyz.openbmc_project.Network.SystemConfiguration", "HostName");
Ed Tanous1abe55e2018-09-05 08:30:59 -07001714 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001715};
1716
1717/**
Ed Tanouscc340dd2018-08-29 13:43:38 -07001718 * SystemActionsReset class supports handle POST method for Reset action.
1719 * The class retrieves and sends data directly to D-Bus.
1720 */
1721class SystemActionsReset : public Node
1722{
1723 public:
Ed Tanous52cc1122020-07-18 13:51:21 -07001724 SystemActionsReset(App& app) :
Ed Tanous029573d2019-02-01 10:57:49 -08001725 Node(app, "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/")
Ed Tanouscc340dd2018-08-29 13:43:38 -07001726 {
1727 entityPrivileges = {
1728 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1729 }
1730
1731 private:
1732 /**
1733 * Function handles POST method request.
1734 * Analyzes POST body message before sends Reset request data to D-Bus.
1735 */
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001736 void doPost(crow::Response& res, const crow::Request& req,
Ed Tanouscb13a392020-07-25 19:02:03 +00001737 const std::vector<std::string>&) override
Ed Tanouscc340dd2018-08-29 13:43:38 -07001738 {
Ed Tanous9712f8a2018-09-21 13:38:49 -07001739 auto asyncResp = std::make_shared<AsyncResp>(res);
1740
1741 std::string resetType;
1742 if (!json_util::readJson(req, res, "ResetType", resetType))
Ed Tanouscc340dd2018-08-29 13:43:38 -07001743 {
1744 return;
1745 }
1746
Jason M. Billsd22c8392019-06-03 13:59:03 -07001747 // Get the command and host vs. chassis
Ed Tanous9712f8a2018-09-21 13:38:49 -07001748 std::string command;
Jason M. Billsd22c8392019-06-03 13:59:03 -07001749 bool hostCommand;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001750 if (resetType == "On")
1751 {
1752 command = "xyz.openbmc_project.State.Host.Transition.On";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001753 hostCommand = true;
1754 }
1755 else if (resetType == "ForceOff")
1756 {
1757 command = "xyz.openbmc_project.State.Chassis.Transition.Off";
1758 hostCommand = false;
1759 }
1760 else if (resetType == "ForceOn")
1761 {
1762 command = "xyz.openbmc_project.State.Host.Transition.On";
1763 hostCommand = true;
1764 }
1765 else if (resetType == "ForceRestart")
1766 {
Jason M. Bills86a08512020-02-04 13:15:49 -08001767 command =
1768 "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
1769 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001770 }
1771 else if (resetType == "GracefulShutdown")
1772 {
1773 command = "xyz.openbmc_project.State.Host.Transition.Off";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001774 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001775 }
1776 else if (resetType == "GracefulRestart")
1777 {
Jason M. Bills86a08512020-02-04 13:15:49 -08001778 command =
1779 "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001780 hostCommand = true;
1781 }
1782 else if (resetType == "PowerCycle")
1783 {
Jason M. Bills86a08512020-02-04 13:15:49 -08001784 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
1785 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001786 }
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001787 else if (resetType == "Nmi")
1788 {
1789 doNMI(asyncResp);
1790 return;
1791 }
Ed Tanous9712f8a2018-09-21 13:38:49 -07001792 else
1793 {
Jason M. Billsf12894f2018-10-09 12:45:45 -07001794 messages::actionParameterUnknown(res, "Reset", resetType);
Ed Tanous9712f8a2018-09-21 13:38:49 -07001795 return;
1796 }
1797
Jason M. Billsd22c8392019-06-03 13:59:03 -07001798 if (hostCommand)
1799 {
1800 crow::connections::systemBus->async_method_call(
1801 [asyncResp, resetType](const boost::system::error_code ec) {
1802 if (ec)
1803 {
1804 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1805 if (ec.value() == boost::asio::error::invalid_argument)
1806 {
1807 messages::actionParameterNotSupported(
1808 asyncResp->res, resetType, "Reset");
1809 }
1810 else
1811 {
1812 messages::internalError(asyncResp->res);
1813 }
1814 return;
1815 }
1816 messages::success(asyncResp->res);
1817 },
1818 "xyz.openbmc_project.State.Host",
1819 "/xyz/openbmc_project/state/host0",
1820 "org.freedesktop.DBus.Properties", "Set",
1821 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
1822 std::variant<std::string>{command});
1823 }
1824 else
1825 {
1826 crow::connections::systemBus->async_method_call(
1827 [asyncResp, resetType](const boost::system::error_code ec) {
1828 if (ec)
1829 {
1830 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1831 if (ec.value() == boost::asio::error::invalid_argument)
1832 {
1833 messages::actionParameterNotSupported(
1834 asyncResp->res, resetType, "Reset");
1835 }
1836 else
1837 {
1838 messages::internalError(asyncResp->res);
1839 }
1840 return;
1841 }
1842 messages::success(asyncResp->res);
1843 },
1844 "xyz.openbmc_project.State.Chassis",
1845 "/xyz/openbmc_project/state/chassis0",
1846 "org.freedesktop.DBus.Properties", "Set",
1847 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
1848 std::variant<std::string>{command});
1849 }
Ed Tanouscc340dd2018-08-29 13:43:38 -07001850 }
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001851 /**
1852 * Function transceives data with dbus directly.
1853 */
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001854 void doNMI(const std::shared_ptr<AsyncResp>& asyncResp)
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001855 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001856 constexpr char const* serviceName =
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001857 "xyz.openbmc_project.Control.Host.NMI";
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001858 constexpr char const* objectPath =
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001859 "/xyz/openbmc_project/control/host0/nmi";
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001860 constexpr char const* interfaceName =
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001861 "xyz.openbmc_project.Control.Host.NMI";
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001862 constexpr char const* method = "NMI";
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001863
1864 crow::connections::systemBus->async_method_call(
1865 [asyncResp](const boost::system::error_code ec) {
1866 if (ec)
1867 {
1868 BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
1869 messages::internalError(asyncResp->res);
1870 return;
1871 }
1872 messages::success(asyncResp->res);
1873 },
1874 serviceName, objectPath, interfaceName, method);
1875 }
Ed Tanouscc340dd2018-08-29 13:43:38 -07001876};
1877
1878/**
Ed Tanous66173382018-08-15 18:20:59 -07001879 * Systems derived class for delivering Computer Systems Schema.
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001880 */
Ed Tanous1abe55e2018-09-05 08:30:59 -07001881class Systems : public Node
1882{
1883 public:
1884 /*
1885 * Default Constructor
1886 */
Ed Tanous52cc1122020-07-18 13:51:21 -07001887 Systems(App& app) : Node(app, "/redfish/v1/Systems/system/")
Ed Tanous1abe55e2018-09-05 08:30:59 -07001888 {
Ed Tanous1abe55e2018-09-05 08:30:59 -07001889 entityPrivileges = {
1890 {boost::beast::http::verb::get, {{"Login"}}},
1891 {boost::beast::http::verb::head, {{"Login"}}},
1892 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1893 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1894 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1895 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001896 }
1897
Ed Tanous1abe55e2018-09-05 08:30:59 -07001898 private:
Ed Tanous1abe55e2018-09-05 08:30:59 -07001899 /**
1900 * Functions triggers appropriate requests on DBus
1901 */
Ed Tanouscb13a392020-07-25 19:02:03 +00001902 void doGet(crow::Response& res, const crow::Request&,
1903 const std::vector<std::string>&) override
Ed Tanous1abe55e2018-09-05 08:30:59 -07001904 {
Gunnar Millsc0557e12020-06-30 11:26:20 -05001905 res.jsonValue["@odata.type"] = "#ComputerSystem.v1_12_0.ComputerSystem";
Gunnar Mills450a25c2020-04-14 21:34:07 -05001906 res.jsonValue["Name"] = "system";
Ed Tanous029573d2019-02-01 10:57:49 -08001907 res.jsonValue["Id"] = "system";
Ed Tanous0f74e642018-11-12 15:17:05 -08001908 res.jsonValue["SystemType"] = "Physical";
1909 res.jsonValue["Description"] = "Computer System";
Ed Tanous0f74e642018-11-12 15:17:05 -08001910 res.jsonValue["ProcessorSummary"]["Count"] = 0;
1911 res.jsonValue["ProcessorSummary"]["Status"]["State"] = "Disabled";
Cheng C Yang5fd7ba62019-11-28 15:58:08 +08001912 res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = uint64_t(0);
Ed Tanous0f74e642018-11-12 15:17:05 -08001913 res.jsonValue["MemorySummary"]["Status"]["State"] = "Disabled";
Ed Tanous029573d2019-02-01 10:57:49 -08001914 res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
Ed Tanous04a258f2018-10-15 08:00:41 -07001915
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001916 res.jsonValue["Processors"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001917 {"@odata.id", "/redfish/v1/Systems/system/Processors"}};
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001918 res.jsonValue["Memory"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001919 {"@odata.id", "/redfish/v1/Systems/system/Memory"}};
Nikhil Potadea25aecc2019-08-23 16:35:26 -07001920 res.jsonValue["Storage"] = {
1921 {"@odata.id", "/redfish/v1/Systems/system/Storage"}};
Ed Tanous029573d2019-02-01 10:57:49 -08001922
Ed Tanouscc340dd2018-08-29 13:43:38 -07001923 res.jsonValue["Actions"]["#ComputerSystem.Reset"] = {
1924 {"target",
Ed Tanous029573d2019-02-01 10:57:49 -08001925 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"},
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05301926 {"@Redfish.ActionInfo",
1927 "/redfish/v1/Systems/system/ResetActionInfo"}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001928
Jason M. Billsc4bf6372018-11-05 13:48:27 -08001929 res.jsonValue["LogServices"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001930 {"@odata.id", "/redfish/v1/Systems/system/LogServices"}};
Jason M. Billsc4bf6372018-11-05 13:48:27 -08001931
Carol Wangd82a3ac2019-11-21 13:56:38 +08001932 res.jsonValue["Bios"] = {
1933 {"@odata.id", "/redfish/v1/Systems/system/Bios"}};
1934
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001935 res.jsonValue["Links"]["ManagedBy"] = {
1936 {{"@odata.id", "/redfish/v1/Managers/bmc"}}};
1937
1938 res.jsonValue["Status"] = {
1939 {"Health", "OK"},
1940 {"State", "Enabled"},
1941 };
Ed Tanousa0803ef2018-08-29 13:29:23 -07001942 auto asyncResp = std::make_shared<AsyncResp>(res);
Ed Tanous1abe55e2018-09-05 08:30:59 -07001943
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001944 constexpr const std::array<const char*, 4> inventoryForSystems = {
James Feistb49ac872019-05-21 15:12:01 -07001945 "xyz.openbmc_project.Inventory.Item.Dimm",
James Feist2ad9c2f2019-10-29 16:26:48 -07001946 "xyz.openbmc_project.Inventory.Item.Cpu",
James Feiste284a7c2019-11-20 16:20:23 -08001947 "xyz.openbmc_project.Inventory.Item.Drive",
1948 "xyz.openbmc_project.Inventory.Item.StorageController"};
James Feistb49ac872019-05-21 15:12:01 -07001949
1950 auto health = std::make_shared<HealthPopulate>(asyncResp);
1951 crow::connections::systemBus->async_method_call(
1952 [health](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001953 std::vector<std::string>& resp) {
James Feistb49ac872019-05-21 15:12:01 -07001954 if (ec)
1955 {
1956 // no inventory
1957 return;
1958 }
1959
1960 health->inventory = std::move(resp);
1961 },
1962 "xyz.openbmc_project.ObjectMapper",
1963 "/xyz/openbmc_project/object_mapper",
1964 "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", "/",
1965 int32_t(0), inventoryForSystems);
1966
1967 health->populate();
1968
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001969 getMainChassisId(asyncResp, [](const std::string& chassisId,
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001970 std::shared_ptr<AsyncResp> aRsp) {
1971 aRsp->res.jsonValue["Links"]["Chassis"] = {
1972 {{"@odata.id", "/redfish/v1/Chassis/" + chassisId}}};
1973 });
AppaRao Pulia3002222019-11-12 21:32:59 +05301974
1975 getIndicatorLedState(asyncResp);
James Feist5bc2dc82019-10-22 14:33:16 -07001976 getComputerSystem(asyncResp, health);
Ed Tanous6c34de42018-08-29 13:37:36 -07001977 getHostState(asyncResp);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301978 getBootProperties(asyncResp);
Jason M. Billsadbe1922019-10-14 15:44:35 -07001979 getPCIeDeviceList(asyncResp, "PCIeDevices");
Yong Li51709ff2019-09-30 14:13:04 +08001980 getHostWatchdogTimer(asyncResp);
George Liuc6a620f2020-04-10 17:18:11 +08001981 getPowerRestorePolicy(asyncResp);
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001982 getAutomaticRetry(asyncResp);
Gunnar Millsc0557e12020-06-30 11:26:20 -05001983 getLastResetTime(asyncResp);
AppaRao Pulia6349912019-10-18 17:16:08 +05301984#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1985 getProvisioningStatus(asyncResp);
1986#endif
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001987 }
1988
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001989 void doPatch(crow::Response& res, const crow::Request& req,
Ed Tanouscb13a392020-07-25 19:02:03 +00001990 const std::vector<std::string>&) override
Ed Tanous1abe55e2018-09-05 08:30:59 -07001991 {
Santosh Puranikcde19e52019-02-20 00:10:56 +05301992 std::optional<std::string> indicatorLed;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301993 std::optional<nlohmann::json> bootProps;
Yong Lic45f0082019-10-10 14:19:01 +08001994 std::optional<nlohmann::json> wdtTimerProps;
George Liuc6a620f2020-04-10 17:18:11 +08001995 std::optional<std::string> powerRestorePolicy;
Santosh Puranik41352c22019-07-03 05:35:49 -05001996 auto asyncResp = std::make_shared<AsyncResp>(res);
1997
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001998 if (!json_util::readJson(req, res, "IndicatorLED", indicatorLed, "Boot",
George Liuc6a620f2020-04-10 17:18:11 +08001999 bootProps, "WatchdogTimer", wdtTimerProps,
2000 "PowerRestorePolicy", powerRestorePolicy))
Ed Tanous66173382018-08-15 18:20:59 -07002001 {
Ed Tanous9712f8a2018-09-21 13:38:49 -07002002 return;
2003 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05302004
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07002005 res.result(boost::beast::http::status::no_content);
Yong Lic45f0082019-10-10 14:19:01 +08002006
2007 if (wdtTimerProps)
2008 {
2009 std::optional<bool> wdtEnable;
2010 std::optional<std::string> wdtTimeOutAction;
2011
2012 if (!json_util::readJson(*wdtTimerProps, asyncResp->res,
2013 "FunctionEnabled", wdtEnable,
2014 "TimeoutAction", wdtTimeOutAction))
2015 {
2016 return;
2017 }
2018 setWDTProperties(asyncResp, std::move(wdtEnable),
2019 std::move(wdtTimeOutAction));
2020 }
2021
Santosh Puranik491d8ee2019-02-06 19:46:56 +05302022 if (bootProps)
2023 {
2024 std::optional<std::string> bootSource;
2025 std::optional<std::string> bootEnable;
Gunnar Mills69f35302020-05-17 16:06:31 -05002026 std::optional<std::string> automaticRetryConfig;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05302027
Gunnar Mills69f35302020-05-17 16:06:31 -05002028 if (!json_util::readJson(
2029 *bootProps, asyncResp->res, "BootSourceOverrideTarget",
2030 bootSource, "BootSourceOverrideEnabled", bootEnable,
2031 "AutomaticRetryConfig", automaticRetryConfig))
Santosh Puranik491d8ee2019-02-06 19:46:56 +05302032 {
2033 return;
2034 }
Gunnar Mills69f35302020-05-17 16:06:31 -05002035 if (bootSource || bootEnable)
2036 {
2037 setBootSourceProperties(asyncResp, std::move(bootSource),
2038 std::move(bootEnable));
2039 }
2040 if (automaticRetryConfig)
2041 {
2042 setAutomaticRetry(asyncResp, std::move(*automaticRetryConfig));
2043 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05302044 }
Johnathan Mantey265c1602019-08-08 11:02:51 -07002045
Ed Tanous9712f8a2018-09-21 13:38:49 -07002046 if (indicatorLed)
2047 {
AppaRao Pulia3002222019-11-12 21:32:59 +05302048 setIndicatorLedState(asyncResp, std::move(*indicatorLed));
Ed Tanous1abe55e2018-09-05 08:30:59 -07002049 }
George Liuc6a620f2020-04-10 17:18:11 +08002050
2051 if (powerRestorePolicy)
2052 {
2053 setPowerRestorePolicy(asyncResp, std::move(*powerRestorePolicy));
2054 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002055 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002056};
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05302057
2058/**
2059 * SystemResetActionInfo derived class for delivering Computer Systems
2060 * ResetType AllowableValues using ResetInfo schema.
2061 */
2062class SystemResetActionInfo : public Node
2063{
2064 public:
2065 /*
2066 * Default Constructor
2067 */
Ed Tanous52cc1122020-07-18 13:51:21 -07002068 SystemResetActionInfo(App& app) :
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05302069 Node(app, "/redfish/v1/Systems/system/ResetActionInfo/")
2070 {
2071 entityPrivileges = {
2072 {boost::beast::http::verb::get, {{"Login"}}},
2073 {boost::beast::http::verb::head, {{"Login"}}},
2074 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
2075 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
2076 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
2077 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
2078 }
2079
2080 private:
2081 /**
2082 * Functions triggers appropriate requests on DBus
2083 */
Ed Tanouscb13a392020-07-25 19:02:03 +00002084 void doGet(crow::Response& res, const crow::Request&,
2085 const std::vector<std::string>&) override
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05302086 {
2087 res.jsonValue = {
2088 {"@odata.type", "#ActionInfo.v1_1_2.ActionInfo"},
2089 {"@odata.id", "/redfish/v1/Systems/system/ResetActionInfo"},
2090 {"Name", "Reset Action Info"},
2091 {"Id", "ResetActionInfo"},
2092 {"Parameters",
2093 {{{"Name", "ResetType"},
2094 {"Required", true},
2095 {"DataType", "String"},
2096 {"AllowableValues",
2097 {"On", "ForceOff", "ForceOn", "ForceRestart", "GracefulRestart",
2098 "GracefulShutdown", "PowerCycle", "Nmi"}}}}}};
2099 res.end();
2100 }
2101};
Ed Tanous1abe55e2018-09-05 08:30:59 -07002102} // namespace redfish