blob: fb1288e6b98dbc90bdbdfc87483d1c522741c97c [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 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500329 for (const auto& property : properties)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500330 {
331 if (property.first ==
332 "ProcessorFamily")
333 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500334 const std::string* value =
Patrick Williams8d78b7a2020-05-13 11:24:20 -0500335 std::get_if<std::string>(
336 &property.second);
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500337 if (value != nullptr)
338 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500339 nlohmann::json&
340 procSummary =
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500341 aResp->res.jsonValue
342 ["ProcessorSumm"
343 "ary"];
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500344 nlohmann::json& procCount =
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500345 procSummary["Count"];
James Feistb4b95952019-12-05 15:01:55 -0800346
347 auto procCountPtr =
348 procCount.get_ptr<
349 nlohmann::json::
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500350 number_integer_t*>();
James Feistb4b95952019-12-05 15:01:55 -0800351 if (procCountPtr != nullptr)
352 {
353 // shouldn't be possible
354 // to be nullptr
355 *procCountPtr += 1;
356 }
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500357 procSummary["Status"]
358 ["State"] =
359 "Enabled";
360 procSummary["Model"] =
361 *value;
362 }
Ed Tanous6c34de42018-08-29 13:37:36 -0700363 }
364 }
Ed Tanous029573d2019-02-01 10:57:49 -0800365 }
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500366 else
367 {
368 auto getCpuPresenceState =
369 [aResp](
370 const boost::system::error_code
Ed Tanouscb13a392020-07-25 19:02:03 +0000371 ec3,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500372 const std::variant<bool>&
373 cpuPresenceCheck) {
Ed Tanouscb13a392020-07-25 19:02:03 +0000374 if (ec3)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500375 {
376 BMCWEB_LOG_ERROR
377 << "DBUS response "
378 "error "
Ed Tanouscb13a392020-07-25 19:02:03 +0000379 << ec3;
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500380 return;
381 }
382 modifyCpuPresenceState(
383 aResp, cpuPresenceCheck);
384 };
385
386 auto getCpuFunctionalState =
387 [aResp](
388 const boost::system::error_code
Ed Tanouscb13a392020-07-25 19:02:03 +0000389 ec3,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500390 const std::variant<bool>&
391 cpuFunctionalCheck) {
Ed Tanouscb13a392020-07-25 19:02:03 +0000392 if (ec3)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500393 {
394 BMCWEB_LOG_ERROR
395 << "DBUS response "
396 "error "
Ed Tanouscb13a392020-07-25 19:02:03 +0000397 << ec3;
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500398 return;
399 }
400 modifyCpuFunctionalState(
401 aResp, cpuFunctionalCheck);
402 };
403 // Get the Presence of CPU
404 crow::connections::systemBus
405 ->async_method_call(
406 std::move(getCpuPresenceState),
407 service, path,
408 "org.freedesktop.DBus."
409 "Properties",
410 "Get",
411 "xyz.openbmc_project.Inventory."
412 "Item",
413 "Present");
414
415 // Get the Functional State
416 crow::connections::systemBus
417 ->async_method_call(
418 std::move(
419 getCpuFunctionalState),
420 service, path,
421 "org.freedesktop.DBus."
422 "Properties",
423 "Get",
424 "xyz.openbmc_project.State."
425 "Decorator."
426 "OperationalStatus",
427 "Functional");
428
429 // Get the MODEL from
430 // xyz.openbmc_project.Inventory.Decorator.Asset
431 // support it later as Model is Empty
432 // currently.
433 }
Ed Tanous029573d2019-02-01 10:57:49 -0800434 },
435 connection.first, path,
436 "org.freedesktop.DBus.Properties", "GetAll",
437 "xyz.openbmc_project.Inventory.Item.Cpu");
James Feist5bc2dc82019-10-22 14:33:16 -0700438
439 cpuHealth->inventory.emplace_back(path);
Ed Tanous029573d2019-02-01 10:57:49 -0800440 }
441 else if (interfaceName ==
442 "xyz.openbmc_project.Common.UUID")
443 {
444 BMCWEB_LOG_DEBUG
445 << "Found UUID, now get its properties.";
446 crow::connections::systemBus->async_method_call(
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500447 [aResp](
Ed Tanouscb13a392020-07-25 19:02:03 +0000448 const boost::system::error_code ec3,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500449 const std::vector<
450 std::pair<std::string, VariantType>>&
451 properties) {
Ed Tanouscb13a392020-07-25 19:02:03 +0000452 if (ec3)
Ed Tanous029573d2019-02-01 10:57:49 -0800453 {
454 BMCWEB_LOG_DEBUG
Ed Tanouscb13a392020-07-25 19:02:03 +0000455 << "DBUS response error " << ec3;
Ed Tanous029573d2019-02-01 10:57:49 -0800456 messages::internalError(aResp->res);
457 return;
458 }
459 BMCWEB_LOG_DEBUG << "Got "
460 << properties.size()
Gunnar Mills698654b2019-10-16 13:17:37 -0500461 << " UUID properties.";
Ed Tanous029573d2019-02-01 10:57:49 -0800462 for (const std::pair<std::string,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500463 VariantType>&
464 property : properties)
Ed Tanous029573d2019-02-01 10:57:49 -0800465 {
Ed Tanous029573d2019-02-01 10:57:49 -0800466 if (property.first == "UUID")
467 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500468 const std::string* value =
Patrick Williams8d78b7a2020-05-13 11:24:20 -0500469 std::get_if<std::string>(
470 &property.second);
Ed Tanous04a258f2018-10-15 08:00:41 -0700471
Ed Tanous029573d2019-02-01 10:57:49 -0800472 if (value != nullptr)
473 {
474 std::string valueStr = *value;
475 if (valueStr.size() == 32)
Ed Tanous6c34de42018-08-29 13:37:36 -0700476 {
Ed Tanous029573d2019-02-01 10:57:49 -0800477 valueStr.insert(8, 1, '-');
478 valueStr.insert(13, 1, '-');
479 valueStr.insert(18, 1, '-');
480 valueStr.insert(23, 1, '-');
Ed Tanous6c34de42018-08-29 13:37:36 -0700481 }
Ed Tanous029573d2019-02-01 10:57:49 -0800482 BMCWEB_LOG_DEBUG << "UUID = "
483 << valueStr;
484 aResp->res.jsonValue["UUID"] =
485 valueStr;
Ed Tanous6c34de42018-08-29 13:37:36 -0700486 }
487 }
Ed Tanous029573d2019-02-01 10:57:49 -0800488 }
489 },
490 connection.first, path,
491 "org.freedesktop.DBus.Properties", "GetAll",
492 "xyz.openbmc_project.Common.UUID");
493 }
494 else if (interfaceName ==
495 "xyz.openbmc_project.Inventory.Item.System")
496 {
497 crow::connections::systemBus->async_method_call(
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500498 [aResp](
Ed Tanouscb13a392020-07-25 19:02:03 +0000499 const boost::system::error_code ec2,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500500 const std::vector<
501 std::pair<std::string, VariantType>>&
502 propertiesList) {
Ed Tanouscb13a392020-07-25 19:02:03 +0000503 if (ec2)
Ed Tanous029573d2019-02-01 10:57:49 -0800504 {
James Feiste4a4b9a2019-06-20 14:08:07 -0700505 // doesn't have to include this
506 // interface
Ed Tanous029573d2019-02-01 10:57:49 -0800507 return;
508 }
Gunnar Mills698654b2019-10-16 13:17:37 -0500509 BMCWEB_LOG_DEBUG
510 << "Got " << propertiesList.size()
511 << " properties for system";
Ed Tanous029573d2019-02-01 10:57:49 -0800512 for (const std::pair<std::string,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500513 VariantType>&
514 property : propertiesList)
Ed Tanous029573d2019-02-01 10:57:49 -0800515 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500516 const std::string& propertyName =
beccabroekfc5afcf2019-03-05 14:35:15 -0600517 property.first;
518 if ((propertyName == "PartNumber") ||
519 (propertyName == "SerialNumber") ||
520 (propertyName == "Manufacturer") ||
521 (propertyName == "Model"))
Ed Tanous029573d2019-02-01 10:57:49 -0800522 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500523 const std::string* value =
beccabroekfc5afcf2019-03-05 14:35:15 -0600524 std::get_if<std::string>(
525 &property.second);
526 if (value != nullptr)
527 {
528 aResp->res
529 .jsonValue[propertyName] =
530 *value;
531 }
Ed Tanous029573d2019-02-01 10:57:49 -0800532 }
533 }
Gunnar Millsc1e236a2020-04-14 21:36:33 -0500534
Andrew Geisslercb7e1e72019-02-19 13:05:38 -0600535 // Grab the bios version
536 fw_util::getActiveFwVersion(
537 aResp, fw_util::biosPurpose,
Gunnar Mills72d566d2020-07-21 12:44:00 -0500538 "BiosVersion", false);
Ed Tanous029573d2019-02-01 10:57:49 -0800539 },
540 connection.first, path,
541 "org.freedesktop.DBus.Properties", "GetAll",
542 "xyz.openbmc_project.Inventory.Decorator."
543 "Asset");
James Feiste4a4b9a2019-06-20 14:08:07 -0700544
545 crow::connections::systemBus->async_method_call(
546 [aResp](
Ed Tanouscb13a392020-07-25 19:02:03 +0000547 const boost::system::error_code ec2,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500548 const std::variant<std::string>& property) {
Ed Tanouscb13a392020-07-25 19:02:03 +0000549 if (ec2)
James Feiste4a4b9a2019-06-20 14:08:07 -0700550 {
551 // doesn't have to include this
552 // interface
553 return;
554 }
555
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500556 const std::string* value =
James Feiste4a4b9a2019-06-20 14:08:07 -0700557 std::get_if<std::string>(&property);
558 if (value != nullptr)
559 {
560 aResp->res.jsonValue["AssetTag"] =
561 *value;
562 }
563 },
564 connection.first, path,
565 "org.freedesktop.DBus.Properties", "Get",
566 "xyz.openbmc_project.Inventory.Decorator."
567 "AssetTag",
568 "AssetTag");
Ed Tanous6c34de42018-08-29 13:37:36 -0700569 }
570 }
571 }
572 }
Ed Tanous6c34de42018-08-29 13:37:36 -0700573 },
574 "xyz.openbmc_project.ObjectMapper",
575 "/xyz/openbmc_project/object_mapper",
576 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
Ed Tanous66173382018-08-15 18:20:59 -0700577 "/xyz/openbmc_project/inventory", int32_t(0),
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500578 std::array<const char*, 5>{
Ed Tanous66173382018-08-15 18:20:59 -0700579 "xyz.openbmc_project.Inventory.Decorator.Asset",
580 "xyz.openbmc_project.Inventory.Item.Cpu",
581 "xyz.openbmc_project.Inventory.Item.Dimm",
582 "xyz.openbmc_project.Inventory.Item.System",
583 "xyz.openbmc_project.Common.UUID",
584 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700585}
586
587/**
Ed Tanous6c34de42018-08-29 13:37:36 -0700588 * @brief Retrieves host state properties over dbus
589 *
590 * @param[in] aResp Shared pointer for completing asynchronous calls.
591 *
592 * @return None.
593 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000594inline void getHostState(std::shared_ptr<AsyncResp> aResp)
Ed Tanous6c34de42018-08-29 13:37:36 -0700595{
596 BMCWEB_LOG_DEBUG << "Get host information.";
597 crow::connections::systemBus->async_method_call(
Jennifer Leec5d03ff2019-03-08 15:42:58 -0800598 [aResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500599 const std::variant<std::string>& hostState) {
Ed Tanous6c34de42018-08-29 13:37:36 -0700600 if (ec)
601 {
602 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700603 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700604 return;
605 }
Ed Tanous66173382018-08-15 18:20:59 -0700606
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500607 const std::string* s = std::get_if<std::string>(&hostState);
Ed Tanous66173382018-08-15 18:20:59 -0700608 BMCWEB_LOG_DEBUG << "Host state: " << *s;
609 if (s != nullptr)
Ed Tanous6c34de42018-08-29 13:37:36 -0700610 {
Ed Tanous66173382018-08-15 18:20:59 -0700611 // Verify Host State
Andrew Geissler94732662019-01-08 19:32:16 -0800612 if (*s == "xyz.openbmc_project.State.Host.HostState.Running")
Ed Tanous6c34de42018-08-29 13:37:36 -0700613 {
Ed Tanous66173382018-08-15 18:20:59 -0700614 aResp->res.jsonValue["PowerState"] = "On";
615 aResp->res.jsonValue["Status"]["State"] = "Enabled";
616 }
Andrew Geissler83935af2020-02-13 10:24:53 -0600617 else if (*s == "xyz.openbmc_project.State.Host.HostState."
Gunnar Mills8c888602020-05-01 14:25:09 -0500618 "Quiesced")
619 {
620 aResp->res.jsonValue["PowerState"] = "On";
621 aResp->res.jsonValue["Status"]["State"] = "Quiesced";
622 }
623 else if (*s == "xyz.openbmc_project.State.Host.HostState."
Andrew Geissler83935af2020-02-13 10:24:53 -0600624 "DiagnosticMode")
625 {
626 aResp->res.jsonValue["PowerState"] = "On";
627 aResp->res.jsonValue["Status"]["State"] = "InTest";
628 }
Ed Tanous66173382018-08-15 18:20:59 -0700629 else
630 {
631 aResp->res.jsonValue["PowerState"] = "Off";
632 aResp->res.jsonValue["Status"]["State"] = "Disabled";
Ed Tanous6c34de42018-08-29 13:37:36 -0700633 }
634 }
635 },
636 "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
Ed Tanous66173382018-08-15 18:20:59 -0700637 "org.freedesktop.DBus.Properties", "Get",
638 "xyz.openbmc_project.State.Host", "CurrentHostState");
Ed Tanous6c34de42018-08-29 13:37:36 -0700639}
640
641/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500642 * @brief Translates boot source DBUS property value to redfish.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530643 *
644 * @param[in] dbusSource The boot source in DBUS speak.
645 *
646 * @return Returns as a string, the boot source in Redfish terms. If translation
647 * cannot be done, returns an empty string.
648 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000649inline std::string dbusToRfBootSource(const std::string& dbusSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530650{
651 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
652 {
653 return "None";
654 }
655 else if (dbusSource ==
656 "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
657 {
658 return "Hdd";
659 }
660 else if (dbusSource ==
Santosh Puranika71dc0b2019-05-23 20:10:49 +0530661 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530662 {
663 return "Cd";
664 }
665 else if (dbusSource ==
666 "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
667 {
668 return "Pxe";
669 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700670 else if (dbusSource ==
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700671 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700672 {
673 return "Usb";
674 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530675 else
676 {
677 return "";
678 }
679}
680
681/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500682 * @brief Translates boot mode DBUS property value to redfish.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530683 *
684 * @param[in] dbusMode The boot mode in DBUS speak.
685 *
686 * @return Returns as a string, the boot mode in Redfish terms. If translation
687 * cannot be done, returns an empty string.
688 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000689inline std::string dbusToRfBootMode(const std::string& dbusMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530690{
691 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
692 {
693 return "None";
694 }
695 else if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
696 {
697 return "Diags";
698 }
699 else if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
700 {
701 return "BiosSetup";
702 }
703 else
704 {
705 return "";
706 }
707}
708
709/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500710 * @brief Translates boot source from Redfish to the DBus boot paths.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530711 *
712 * @param[in] rfSource The boot source in Redfish.
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700713 * @param[out] bootSource The DBus source
714 * @param[out] bootMode the DBus boot mode
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530715 *
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700716 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530717 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000718inline int assignBootParameters(std::shared_ptr<AsyncResp> aResp,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500719 const std::string& rfSource,
720 std::string& bootSource, std::string& bootMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530721{
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700722 // The caller has initialized the bootSource and bootMode to:
723 // bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
724 // bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
725 // Only modify the bootSource/bootMode variable needed to achieve the
726 // desired boot action.
727
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530728 if (rfSource == "None")
729 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700730 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530731 }
732 else if (rfSource == "Pxe")
733 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700734 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
735 }
736 else if (rfSource == "Hdd")
737 {
738 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
739 }
740 else if (rfSource == "Diags")
741 {
742 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
743 }
744 else if (rfSource == "Cd")
745 {
746 bootSource =
747 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
748 }
749 else if (rfSource == "BiosSetup")
750 {
751 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530752 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700753 else if (rfSource == "Usb")
754 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700755 bootSource =
756 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700757 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530758 else
759 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700760 BMCWEB_LOG_DEBUG << "Invalid property value for "
761 "BootSourceOverrideTarget: "
762 << bootSource;
763 messages::propertyValueNotInList(aResp->res, rfSource,
764 "BootSourceTargetOverride");
765 return -1;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530766 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700767 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530768}
769
770/**
771 * @brief Retrieves boot mode over DBUS and fills out the response
772 *
773 * @param[in] aResp Shared pointer for generating response message.
774 * @param[in] bootDbusObj The dbus object to query for boot properties.
775 *
776 * @return None.
777 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000778inline void getBootMode(std::shared_ptr<AsyncResp> aResp,
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530779 std::string bootDbusObj)
780{
781 crow::connections::systemBus->async_method_call(
782 [aResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500783 const std::variant<std::string>& bootMode) {
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530784 if (ec)
785 {
786 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
787 messages::internalError(aResp->res);
788 return;
789 }
790
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500791 const std::string* bootModeStr =
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530792 std::get_if<std::string>(&bootMode);
793
794 if (!bootModeStr)
795 {
796 messages::internalError(aResp->res);
797 return;
798 }
799
800 BMCWEB_LOG_DEBUG << "Boot mode: " << *bootModeStr;
801
802 // TODO (Santosh): Do we need to support override mode?
803 aResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = "Legacy";
804 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget@Redfish."
805 "AllowableValues"] = {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700806 "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530807
808 if (*bootModeStr !=
809 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
810 {
811 auto rfMode = dbusToRfBootMode(*bootModeStr);
812 if (!rfMode.empty())
813 {
814 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
815 rfMode;
816 }
817 }
818
819 // If the BootSourceOverrideTarget is still "None" at the end,
820 // reset the BootSourceOverrideEnabled to indicate that
821 // overrides are disabled
822 if (aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] ==
823 "None")
824 {
825 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
826 "Disabled";
827 }
828 },
829 "xyz.openbmc_project.Settings", bootDbusObj,
830 "org.freedesktop.DBus.Properties", "Get",
831 "xyz.openbmc_project.Control.Boot.Mode", "BootMode");
832}
833
834/**
835 * @brief Retrieves boot source over DBUS
836 *
837 * @param[in] aResp Shared pointer for generating response message.
838 * @param[in] oneTimeEnable Boolean to indicate boot properties are one-time.
839 *
840 * @return None.
841 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000842inline void getBootSource(std::shared_ptr<AsyncResp> aResp, bool oneTimeEnabled)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530843{
844 std::string bootDbusObj =
845 oneTimeEnabled ? "/xyz/openbmc_project/control/host0/boot/one_time"
846 : "/xyz/openbmc_project/control/host0/boot";
847
848 BMCWEB_LOG_DEBUG << "Is one time: " << oneTimeEnabled;
849 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
850 (oneTimeEnabled) ? "Once" : "Continuous";
851
852 crow::connections::systemBus->async_method_call(
853 [aResp, bootDbusObj](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500854 const std::variant<std::string>& bootSource) {
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530855 if (ec)
856 {
857 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
858 messages::internalError(aResp->res);
859 return;
860 }
861
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500862 const std::string* bootSourceStr =
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530863 std::get_if<std::string>(&bootSource);
864
865 if (!bootSourceStr)
866 {
867 messages::internalError(aResp->res);
868 return;
869 }
870 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSourceStr;
871
872 auto rfSource = dbusToRfBootSource(*bootSourceStr);
873 if (!rfSource.empty())
874 {
875 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
876 rfSource;
877 }
878 },
879 "xyz.openbmc_project.Settings", bootDbusObj,
880 "org.freedesktop.DBus.Properties", "Get",
881 "xyz.openbmc_project.Control.Boot.Source", "BootSource");
882 getBootMode(std::move(aResp), std::move(bootDbusObj));
883}
884
885/**
886 * @brief Retrieves "One time" enabled setting over DBUS and calls function to
887 * get boot source and boot mode.
888 *
889 * @param[in] aResp Shared pointer for generating response message.
890 *
891 * @return None.
892 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000893inline void getBootProperties(std::shared_ptr<AsyncResp> aResp)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530894{
895 BMCWEB_LOG_DEBUG << "Get boot information.";
896
897 crow::connections::systemBus->async_method_call(
Jennifer Leec5d03ff2019-03-08 15:42:58 -0800898 [aResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500899 const std::variant<bool>& oneTime) {
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530900 if (ec)
901 {
902 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
James Feist2a833c72019-07-19 10:17:13 -0700903 // not an error, don't have to have the interface
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530904 return;
905 }
906
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500907 const bool* oneTimePtr = std::get_if<bool>(&oneTime);
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530908
909 if (!oneTimePtr)
910 {
911 messages::internalError(aResp->res);
912 return;
913 }
914 getBootSource(aResp, *oneTimePtr);
915 },
916 "xyz.openbmc_project.Settings",
917 "/xyz/openbmc_project/control/host0/boot/one_time",
918 "org.freedesktop.DBus.Properties", "Get",
919 "xyz.openbmc_project.Object.Enable", "Enabled");
920}
921
922/**
Gunnar Millsc0557e12020-06-30 11:26:20 -0500923 * @brief Retrieves the Last Reset Time
924 *
925 * "Reset" is an overloaded term in Redfish, "Reset" includes power on
926 * and power off. Even though this is the "system" Redfish object look at the
927 * chassis D-Bus interface for the LastStateChangeTime since this has the
928 * last power operation time.
929 *
930 * @param[in] aResp Shared pointer for generating response message.
931 *
932 * @return None.
933 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000934inline void getLastResetTime(std::shared_ptr<AsyncResp> aResp)
Gunnar Millsc0557e12020-06-30 11:26:20 -0500935{
936 BMCWEB_LOG_DEBUG << "Getting System Last Reset Time";
937
938 crow::connections::systemBus->async_method_call(
939 [aResp](const boost::system::error_code ec,
940 std::variant<uint64_t>& lastResetTime) {
941 if (ec)
942 {
943 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
944 return;
945 }
946
947 const uint64_t* lastResetTimePtr =
948 std::get_if<uint64_t>(&lastResetTime);
949
950 if (!lastResetTimePtr)
951 {
952 messages::internalError(aResp->res);
953 return;
954 }
955 // LastStateChangeTime is epoch time, in milliseconds
956 // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
957 time_t lastResetTimeStamp =
958 static_cast<time_t>(*lastResetTimePtr / 1000);
959
960 // Convert to ISO 8601 standard
961 aResp->res.jsonValue["LastResetTime"] =
962 crow::utility::getDateTime(lastResetTimeStamp);
963 },
964 "xyz.openbmc_project.State.Chassis",
965 "/xyz/openbmc_project/state/chassis0",
966 "org.freedesktop.DBus.Properties", "Get",
967 "xyz.openbmc_project.State.Chassis", "LastStateChangeTime");
968}
969
970/**
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -0500971 * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
972 *
973 * @param[in] aResp Shared pointer for generating response message.
974 *
975 * @return None.
976 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000977inline void getAutomaticRetry(std::shared_ptr<AsyncResp> aResp)
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -0500978{
979 BMCWEB_LOG_DEBUG << "Get Automatic Retry policy";
980
981 crow::connections::systemBus->async_method_call(
982 [aResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500983 std::variant<bool>& autoRebootEnabled) {
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -0500984 if (ec)
985 {
986 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
987 return;
988 }
989
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500990 const bool* autoRebootEnabledPtr =
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -0500991 std::get_if<bool>(&autoRebootEnabled);
992
993 if (!autoRebootEnabledPtr)
994 {
995 messages::internalError(aResp->res);
996 return;
997 }
998
999 BMCWEB_LOG_DEBUG << "Auto Reboot: " << *autoRebootEnabledPtr;
1000 if (*autoRebootEnabledPtr == true)
1001 {
1002 aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
1003 "RetryAttempts";
1004 // If AutomaticRetry (AutoReboot) is enabled see how many
1005 // attempts are left
1006 crow::connections::systemBus->async_method_call(
Ed Tanouscb13a392020-07-25 19:02:03 +00001007 [aResp](const boost::system::error_code ec2,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001008 std::variant<uint32_t>& autoRebootAttemptsLeft) {
Ed Tanouscb13a392020-07-25 19:02:03 +00001009 if (ec2)
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001010 {
Ed Tanouscb13a392020-07-25 19:02:03 +00001011 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec2;
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001012 return;
1013 }
1014
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001015 const uint32_t* autoRebootAttemptsLeftPtr =
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001016 std::get_if<uint32_t>(&autoRebootAttemptsLeft);
1017
1018 if (!autoRebootAttemptsLeftPtr)
1019 {
1020 messages::internalError(aResp->res);
1021 return;
1022 }
1023
1024 BMCWEB_LOG_DEBUG << "Auto Reboot Attempts Left: "
1025 << *autoRebootAttemptsLeftPtr;
1026
1027 aResp->res
1028 .jsonValue["Boot"]
1029 ["RemainingAutomaticRetryAttempts"] =
1030 *autoRebootAttemptsLeftPtr;
1031 },
1032 "xyz.openbmc_project.State.Host",
1033 "/xyz/openbmc_project/state/host0",
1034 "org.freedesktop.DBus.Properties", "Get",
1035 "xyz.openbmc_project.Control.Boot.RebootAttempts",
1036 "AttemptsLeft");
1037 }
1038 else
1039 {
1040 aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
1041 "Disabled";
1042 }
1043
1044 // Not on D-Bus. Hardcoded here:
1045 // https://github.com/openbmc/phosphor-state-manager/blob/1dbbef42675e94fb1f78edb87d6b11380260535a/meson_options.txt#L71
1046 aResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] = 3;
Gunnar Mills69f35302020-05-17 16:06:31 -05001047
1048 // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
1049 // and RetryAttempts. OpenBMC only supports Disabled and
1050 // RetryAttempts.
1051 aResp->res.jsonValue["Boot"]["AutomaticRetryConfig@Redfish."
1052 "AllowableValues"] = {"Disabled",
1053 "RetryAttempts"};
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001054 },
1055 "xyz.openbmc_project.Settings",
1056 "/xyz/openbmc_project/control/host0/auto_reboot",
1057 "org.freedesktop.DBus.Properties", "Get",
1058 "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot");
1059}
1060
1061/**
George Liuc6a620f2020-04-10 17:18:11 +08001062 * @brief Retrieves power restore policy over DBUS.
1063 *
1064 * @param[in] aResp Shared pointer for generating response message.
1065 *
1066 * @return None.
1067 */
Ed Tanous23a21a12020-07-25 04:45:05 +00001068inline void getPowerRestorePolicy(std::shared_ptr<AsyncResp> aResp)
George Liuc6a620f2020-04-10 17:18:11 +08001069{
1070 BMCWEB_LOG_DEBUG << "Get power restore policy";
1071
1072 crow::connections::systemBus->async_method_call(
1073 [aResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001074 std::variant<std::string>& policy) {
George Liuc6a620f2020-04-10 17:18:11 +08001075 if (ec)
1076 {
1077 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1078 return;
1079 }
1080
1081 const boost::container::flat_map<std::string, std::string>
1082 policyMaps = {
1083 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1084 "AlwaysOn",
1085 "AlwaysOn"},
1086 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1087 "AlwaysOff",
1088 "AlwaysOff"},
1089 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1090 "LastState",
1091 "LastState"}};
1092
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001093 const std::string* policyPtr = std::get_if<std::string>(&policy);
George Liuc6a620f2020-04-10 17:18:11 +08001094
1095 if (!policyPtr)
1096 {
1097 messages::internalError(aResp->res);
1098 return;
1099 }
1100
1101 auto policyMapsIt = policyMaps.find(*policyPtr);
1102 if (policyMapsIt == policyMaps.end())
1103 {
1104 messages::internalError(aResp->res);
1105 return;
1106 }
1107
1108 aResp->res.jsonValue["PowerRestorePolicy"] = policyMapsIt->second;
1109 },
1110 "xyz.openbmc_project.Settings",
1111 "/xyz/openbmc_project/control/host0/power_restore_policy",
1112 "org.freedesktop.DBus.Properties", "Get",
1113 "xyz.openbmc_project.Control.Power.RestorePolicy",
1114 "PowerRestorePolicy");
1115}
1116
1117/**
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301118 * @brief Sets boot properties into DBUS object(s).
1119 *
1120 * @param[in] aResp Shared pointer for generating response message.
1121 * @param[in] oneTimeEnabled Is "one-time" setting already enabled.
1122 * @param[in] bootSource The boot source to set.
1123 * @param[in] bootEnable The source override "enable" to set.
1124 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001125 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301126 */
Ed Tanous23a21a12020-07-25 04:45:05 +00001127inline void setBootModeOrSource(std::shared_ptr<AsyncResp> aResp,
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301128 bool oneTimeEnabled,
1129 std::optional<std::string> bootSource,
1130 std::optional<std::string> bootEnable)
1131{
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001132 std::string bootSourceStr =
1133 "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
1134 std::string bootModeStr =
1135 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301136 bool oneTimeSetting = oneTimeEnabled;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001137 bool useBootSource = true;
1138
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301139 // Validate incoming parameters
1140 if (bootEnable)
1141 {
1142 if (*bootEnable == "Once")
1143 {
1144 oneTimeSetting = true;
1145 }
1146 else if (*bootEnable == "Continuous")
1147 {
1148 oneTimeSetting = false;
1149 }
1150 else if (*bootEnable == "Disabled")
1151 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001152 BMCWEB_LOG_DEBUG << "Boot source override will be disabled";
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301153 oneTimeSetting = false;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001154 useBootSource = false;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301155 }
1156 else
1157 {
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301158 BMCWEB_LOG_DEBUG << "Unsupported value for "
1159 "BootSourceOverrideEnabled: "
1160 << *bootEnable;
1161 messages::propertyValueNotInList(aResp->res, *bootEnable,
1162 "BootSourceOverrideEnabled");
1163 return;
1164 }
1165 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301166
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001167 if (bootSource && useBootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301168 {
1169 // Source target specified
1170 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource;
1171 // Figure out which DBUS interface and property to use
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001172 if (assignBootParameters(aResp, *bootSource, bootSourceStr,
1173 bootModeStr))
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301174 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001175 BMCWEB_LOG_DEBUG
1176 << "Invalid property value for BootSourceOverrideTarget: "
1177 << *bootSource;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301178 messages::propertyValueNotInList(aResp->res, *bootSource,
1179 "BootSourceTargetOverride");
1180 return;
1181 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001182 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301183
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001184 // Act on validated parameters
1185 BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
1186 BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001187 const char* bootObj =
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001188 oneTimeSetting ? "/xyz/openbmc_project/control/host0/boot/one_time"
1189 : "/xyz/openbmc_project/control/host0/boot";
1190
1191 crow::connections::systemBus->async_method_call(
1192 [aResp](const boost::system::error_code ec) {
1193 if (ec)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301194 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001195 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1196 messages::internalError(aResp->res);
1197 return;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301198 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001199 BMCWEB_LOG_DEBUG << "Boot source update done.";
1200 },
1201 "xyz.openbmc_project.Settings", bootObj,
1202 "org.freedesktop.DBus.Properties", "Set",
1203 "xyz.openbmc_project.Control.Boot.Source", "BootSource",
1204 std::variant<std::string>(bootSourceStr));
1205
1206 crow::connections::systemBus->async_method_call(
1207 [aResp](const boost::system::error_code ec) {
1208 if (ec)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301209 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001210 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1211 messages::internalError(aResp->res);
1212 return;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301213 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001214 BMCWEB_LOG_DEBUG << "Boot mode update done.";
1215 },
1216 "xyz.openbmc_project.Settings", bootObj,
1217 "org.freedesktop.DBus.Properties", "Set",
1218 "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
1219 std::variant<std::string>(bootModeStr));
1220
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301221 crow::connections::systemBus->async_method_call(
1222 [aResp{std::move(aResp)}](const boost::system::error_code ec) {
1223 if (ec)
1224 {
1225 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1226 messages::internalError(aResp->res);
1227 return;
1228 }
1229 BMCWEB_LOG_DEBUG << "Boot enable update done.";
1230 },
1231 "xyz.openbmc_project.Settings",
1232 "/xyz/openbmc_project/control/host0/boot/one_time",
1233 "org.freedesktop.DBus.Properties", "Set",
1234 "xyz.openbmc_project.Object.Enable", "Enabled",
1235 std::variant<bool>(oneTimeSetting));
1236}
1237
1238/**
1239 * @brief Retrieves "One time" enabled setting over DBUS and calls function to
1240 * set boot source/boot mode properties.
1241 *
1242 * @param[in] aResp Shared pointer for generating response message.
1243 * @param[in] bootSource The boot source from incoming RF request.
1244 * @param[in] bootEnable The boot override enable from incoming RF request.
1245 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001246 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301247 */
Ed Tanous23a21a12020-07-25 04:45:05 +00001248inline void setBootSourceProperties(std::shared_ptr<AsyncResp> aResp,
Gunnar Mills69f35302020-05-17 16:06:31 -05001249 std::optional<std::string> bootSource,
1250 std::optional<std::string> bootEnable)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301251{
1252 BMCWEB_LOG_DEBUG << "Set boot information.";
1253
1254 crow::connections::systemBus->async_method_call(
Johnathan Mantey265c1602019-08-08 11:02:51 -07001255 [aResp, bootSource{std::move(bootSource)},
Patrick Williams19bd78d2020-05-13 17:38:24 -05001256 bootEnable{std::move(bootEnable)}](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001257 const std::variant<bool>& oneTime) {
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301258 if (ec)
1259 {
1260 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1261 messages::internalError(aResp->res);
1262 return;
1263 }
1264
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001265 const bool* oneTimePtr = std::get_if<bool>(&oneTime);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301266
1267 if (!oneTimePtr)
1268 {
1269 messages::internalError(aResp->res);
1270 return;
1271 }
1272
1273 BMCWEB_LOG_DEBUG << "Got one time: " << *oneTimePtr;
1274
1275 setBootModeOrSource(aResp, *oneTimePtr, std::move(bootSource),
1276 std::move(bootEnable));
1277 },
1278 "xyz.openbmc_project.Settings",
1279 "/xyz/openbmc_project/control/host0/boot/one_time",
1280 "org.freedesktop.DBus.Properties", "Get",
1281 "xyz.openbmc_project.Object.Enable", "Enabled");
1282}
1283
George Liuc6a620f2020-04-10 17:18:11 +08001284/**
Gunnar Mills69f35302020-05-17 16:06:31 -05001285 * @brief Sets automaticRetry (Auto Reboot)
1286 *
1287 * @param[in] aResp Shared pointer for generating response message.
1288 * @param[in] automaticRetryConfig "AutomaticRetryConfig" from request.
1289 *
1290 * @return None.
1291 */
Ed Tanous23a21a12020-07-25 04:45:05 +00001292inline void setAutomaticRetry(std::shared_ptr<AsyncResp> aResp,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001293 const std::string&& automaticRetryConfig)
Gunnar Mills69f35302020-05-17 16:06:31 -05001294{
1295 BMCWEB_LOG_DEBUG << "Set Automatic Retry.";
1296
1297 // OpenBMC only supports "Disabled" and "RetryAttempts".
1298 bool autoRebootEnabled;
1299
1300 if (automaticRetryConfig == "Disabled")
1301 {
1302 autoRebootEnabled = false;
1303 }
1304 else if (automaticRetryConfig == "RetryAttempts")
1305 {
1306 autoRebootEnabled = true;
1307 }
1308 else
1309 {
1310 BMCWEB_LOG_DEBUG << "Invalid property value for "
1311 "AutomaticRetryConfig: "
1312 << automaticRetryConfig;
1313 messages::propertyValueNotInList(aResp->res, automaticRetryConfig,
1314 "AutomaticRetryConfig");
1315 return;
1316 }
1317
1318 crow::connections::systemBus->async_method_call(
1319 [aResp](const boost::system::error_code ec) {
1320 if (ec)
1321 {
1322 messages::internalError(aResp->res);
1323 return;
1324 }
1325 },
1326 "xyz.openbmc_project.Settings",
1327 "/xyz/openbmc_project/control/host0/auto_reboot",
1328 "org.freedesktop.DBus.Properties", "Set",
1329 "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
1330 std::variant<bool>(autoRebootEnabled));
1331}
1332
1333/**
George Liuc6a620f2020-04-10 17:18:11 +08001334 * @brief Sets power restore policy properties.
1335 *
1336 * @param[in] aResp Shared pointer for generating response message.
1337 * @param[in] policy power restore policy properties from request.
1338 *
1339 * @return None.
1340 */
Ed Tanous23a21a12020-07-25 04:45:05 +00001341inline void setPowerRestorePolicy(std::shared_ptr<AsyncResp> aResp,
George Liuc6a620f2020-04-10 17:18:11 +08001342 std::optional<std::string> policy)
1343{
1344 BMCWEB_LOG_DEBUG << "Set power restore policy.";
1345
1346 const boost::container::flat_map<std::string, std::string> policyMaps = {
1347 {"AlwaysOn", "xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1348 "AlwaysOn"},
1349 {"AlwaysOff", "xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1350 "AlwaysOff"},
1351 {"LastState", "xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1352 "LastState"}};
1353
1354 std::string powerRestorPolicy;
1355
1356 auto policyMapsIt = policyMaps.find(*policy);
1357 if (policyMapsIt == policyMaps.end())
1358 {
1359 messages::internalError(aResp->res);
1360 return;
1361 }
1362
1363 powerRestorPolicy = policyMapsIt->second;
1364
1365 crow::connections::systemBus->async_method_call(
1366 [aResp](const boost::system::error_code ec) {
1367 if (ec)
1368 {
1369 messages::internalError(aResp->res);
1370 return;
1371 }
1372 },
1373 "xyz.openbmc_project.Settings",
1374 "/xyz/openbmc_project/control/host0/power_restore_policy",
1375 "org.freedesktop.DBus.Properties", "Set",
1376 "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
1377 std::variant<std::string>(powerRestorPolicy));
1378}
1379
AppaRao Pulia6349912019-10-18 17:16:08 +05301380#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1381/**
1382 * @brief Retrieves provisioning status
1383 *
1384 * @param[in] aResp Shared pointer for completing asynchronous calls.
1385 *
1386 * @return None.
1387 */
Ed Tanous23a21a12020-07-25 04:45:05 +00001388inline void getProvisioningStatus(std::shared_ptr<AsyncResp> aResp)
AppaRao Pulia6349912019-10-18 17:16:08 +05301389{
1390 BMCWEB_LOG_DEBUG << "Get OEM information.";
1391 crow::connections::systemBus->async_method_call(
1392 [aResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001393 const std::vector<std::pair<std::string, VariantType>>&
1394 propertiesList) {
AppaRao Pulib99fb1a2020-07-08 16:42:48 +05301395 nlohmann::json& oemPFR =
1396 aResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
AppaRao Pulia6349912019-10-18 17:16:08 +05301397 if (ec)
1398 {
1399 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
AppaRao Pulib99fb1a2020-07-08 16:42:48 +05301400 // not an error, don't have to have the interface
1401 oemPFR["ProvisioningStatus"] = "NotProvisioned";
AppaRao Pulia6349912019-10-18 17:16:08 +05301402 return;
1403 }
1404
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001405 const bool* provState = nullptr;
1406 const bool* lockState = nullptr;
1407 for (const std::pair<std::string, VariantType>& property :
AppaRao Pulia6349912019-10-18 17:16:08 +05301408 propertiesList)
1409 {
1410 if (property.first == "UfmProvisioned")
1411 {
1412 provState = std::get_if<bool>(&property.second);
1413 }
1414 else if (property.first == "UfmLocked")
1415 {
1416 lockState = std::get_if<bool>(&property.second);
1417 }
1418 }
1419
1420 if ((provState == nullptr) || (lockState == nullptr))
1421 {
1422 BMCWEB_LOG_DEBUG << "Unable to get PFR attributes.";
1423 messages::internalError(aResp->res);
1424 return;
1425 }
1426
AppaRao Pulia6349912019-10-18 17:16:08 +05301427 if (*provState == true)
1428 {
1429 if (*lockState == true)
1430 {
1431 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
1432 }
1433 else
1434 {
1435 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
1436 }
1437 }
1438 else
1439 {
1440 oemPFR["ProvisioningStatus"] = "NotProvisioned";
1441 }
1442 },
1443 "xyz.openbmc_project.PFR.Manager", "/xyz/openbmc_project/pfr",
1444 "org.freedesktop.DBus.Properties", "GetAll",
1445 "xyz.openbmc_project.PFR.Attributes");
1446}
1447#endif
1448
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301449/**
Yong Li51709ff2019-09-30 14:13:04 +08001450 * @brief Translates watchdog timeout action DBUS property value to redfish.
1451 *
1452 * @param[in] dbusAction The watchdog timeout action in D-BUS.
1453 *
1454 * @return Returns as a string, the timeout action in Redfish terms. If
1455 * translation cannot be done, returns an empty string.
1456 */
Ed Tanous23a21a12020-07-25 04:45:05 +00001457inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
Yong Li51709ff2019-09-30 14:13:04 +08001458{
1459 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
1460 {
1461 return "None";
1462 }
1463 else if (dbusAction ==
1464 "xyz.openbmc_project.State.Watchdog.Action.HardReset")
1465 {
1466 return "ResetSystem";
1467 }
1468 else if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
1469 {
1470 return "PowerDown";
1471 }
1472 else if (dbusAction ==
1473 "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
1474 {
1475 return "PowerCycle";
1476 }
1477
1478 return "";
1479}
1480
1481/**
Yong Lic45f0082019-10-10 14:19:01 +08001482 *@brief Translates timeout action from Redfish to DBUS property value.
1483 *
1484 *@param[in] rfAction The timeout action in Redfish.
1485 *
1486 *@return Returns as a string, the time_out action as expected by DBUS.
1487 *If translation cannot be done, returns an empty string.
1488 */
1489
Ed Tanous23a21a12020-07-25 04:45:05 +00001490inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
Yong Lic45f0082019-10-10 14:19:01 +08001491{
1492 if (rfAction == "None")
1493 {
1494 return "xyz.openbmc_project.State.Watchdog.Action.None";
1495 }
1496 else if (rfAction == "PowerCycle")
1497 {
1498 return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
1499 }
1500 else if (rfAction == "PowerDown")
1501 {
1502 return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
1503 }
1504 else if (rfAction == "ResetSystem")
1505 {
1506 return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
1507 }
1508
1509 return "";
1510}
1511
1512/**
Yong Li51709ff2019-09-30 14:13:04 +08001513 * @brief Retrieves host watchdog timer properties over DBUS
1514 *
1515 * @param[in] aResp Shared pointer for completing asynchronous calls.
1516 *
1517 * @return None.
1518 */
Ed Tanous23a21a12020-07-25 04:45:05 +00001519inline void getHostWatchdogTimer(std::shared_ptr<AsyncResp> aResp)
Yong Li51709ff2019-09-30 14:13:04 +08001520{
1521 BMCWEB_LOG_DEBUG << "Get host watchodg";
1522 crow::connections::systemBus->async_method_call(
1523 [aResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001524 PropertiesType& properties) {
Yong Li51709ff2019-09-30 14:13:04 +08001525 if (ec)
1526 {
1527 // watchdog service is stopped
1528 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1529 return;
1530 }
1531
1532 BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop.";
1533
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001534 nlohmann::json& hostWatchdogTimer =
Yong Li51709ff2019-09-30 14:13:04 +08001535 aResp->res.jsonValue["HostWatchdogTimer"];
1536
1537 // watchdog service is running/enabled
1538 hostWatchdogTimer["Status"]["State"] = "Enabled";
1539
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001540 for (const auto& property : properties)
Yong Li51709ff2019-09-30 14:13:04 +08001541 {
1542 BMCWEB_LOG_DEBUG << "prop=" << property.first;
1543 if (property.first == "Enabled")
1544 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001545 const bool* state = std::get_if<bool>(&property.second);
Yong Li51709ff2019-09-30 14:13:04 +08001546
1547 if (!state)
1548 {
1549 messages::internalError(aResp->res);
1550 continue;
1551 }
1552
1553 hostWatchdogTimer["FunctionEnabled"] = *state;
1554 }
1555 else if (property.first == "ExpireAction")
1556 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001557 const std::string* s =
Yong Li51709ff2019-09-30 14:13:04 +08001558 std::get_if<std::string>(&property.second);
1559 if (!s)
1560 {
1561 messages::internalError(aResp->res);
1562 continue;
1563 }
1564
1565 std::string action = dbusToRfWatchdogAction(*s);
1566 if (action.empty())
1567 {
1568 messages::internalError(aResp->res);
1569 continue;
1570 }
1571 hostWatchdogTimer["TimeoutAction"] = action;
1572 }
1573 }
1574 },
1575 "xyz.openbmc_project.Watchdog", "/xyz/openbmc_project/watchdog/host0",
1576 "org.freedesktop.DBus.Properties", "GetAll",
1577 "xyz.openbmc_project.State.Watchdog");
1578}
1579
1580/**
Yong Lic45f0082019-10-10 14:19:01 +08001581 * @brief Sets Host WatchDog Timer properties.
1582 *
1583 * @param[in] aResp Shared pointer for generating response message.
1584 * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming
1585 * RF request.
1586 * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
1587 *
1588 * @return None.
1589 */
Ed Tanous23a21a12020-07-25 04:45:05 +00001590inline void setWDTProperties(std::shared_ptr<AsyncResp> aResp,
Yong Lic45f0082019-10-10 14:19:01 +08001591 const std::optional<bool> wdtEnable,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001592 const std::optional<std::string>& wdtTimeOutAction)
Yong Lic45f0082019-10-10 14:19:01 +08001593{
1594 BMCWEB_LOG_DEBUG << "Set host watchdog";
1595
1596 if (wdtTimeOutAction)
1597 {
1598 std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
1599 // check if TimeOut Action is Valid
1600 if (wdtTimeOutActStr.empty())
1601 {
1602 BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: "
1603 << *wdtTimeOutAction;
1604 messages::propertyValueNotInList(aResp->res, *wdtTimeOutAction,
1605 "TimeoutAction");
1606 return;
1607 }
1608
1609 crow::connections::systemBus->async_method_call(
1610 [aResp](const boost::system::error_code ec) {
1611 if (ec)
1612 {
1613 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1614 messages::internalError(aResp->res);
1615 return;
1616 }
1617 },
1618 "xyz.openbmc_project.Watchdog",
1619 "/xyz/openbmc_project/watchdog/host0",
1620 "org.freedesktop.DBus.Properties", "Set",
1621 "xyz.openbmc_project.State.Watchdog", "ExpireAction",
1622 std::variant<std::string>(wdtTimeOutActStr));
1623 }
1624
1625 if (wdtEnable)
1626 {
1627 crow::connections::systemBus->async_method_call(
1628 [aResp](const boost::system::error_code ec) {
1629 if (ec)
1630 {
1631 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1632 messages::internalError(aResp->res);
1633 return;
1634 }
1635 },
1636 "xyz.openbmc_project.Watchdog",
1637 "/xyz/openbmc_project/watchdog/host0",
1638 "org.freedesktop.DBus.Properties", "Set",
1639 "xyz.openbmc_project.State.Watchdog", "Enabled",
1640 std::variant<bool>(*wdtEnable));
1641 }
1642}
1643
1644/**
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001645 * SystemsCollection derived class for delivering ComputerSystems Collection
1646 * Schema
1647 */
Ed Tanous1abe55e2018-09-05 08:30:59 -07001648class SystemsCollection : public Node
1649{
1650 public:
Ed Tanous52cc1122020-07-18 13:51:21 -07001651 SystemsCollection(App& app) : Node(app, "/redfish/v1/Systems/")
Ed Tanous1abe55e2018-09-05 08:30:59 -07001652 {
Ed Tanous1abe55e2018-09-05 08:30:59 -07001653 entityPrivileges = {
1654 {boost::beast::http::verb::get, {{"Login"}}},
1655 {boost::beast::http::verb::head, {{"Login"}}},
1656 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1657 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1658 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1659 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1660 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001661
Ed Tanous1abe55e2018-09-05 08:30:59 -07001662 private:
Ed Tanouscb13a392020-07-25 19:02:03 +00001663 void doGet(crow::Response& res, const crow::Request&,
1664 const std::vector<std::string>&) override
Ed Tanous1abe55e2018-09-05 08:30:59 -07001665 {
Sunitha Harish462023a2020-02-19 08:34:59 -06001666 std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
Ed Tanous0f74e642018-11-12 15:17:05 -08001667 res.jsonValue["@odata.type"] =
1668 "#ComputerSystemCollection.ComputerSystemCollection";
1669 res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
Ed Tanous0f74e642018-11-12 15:17:05 -08001670 res.jsonValue["Name"] = "Computer System Collection";
Sunitha Harish462023a2020-02-19 08:34:59 -06001671
1672 crow::connections::systemBus->async_method_call(
1673 [asyncResp](const boost::system::error_code ec,
Ed Tanouscb13a392020-07-25 19:02:03 +00001674 const std::variant<std::string>& /*hostName*/) {
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001675 nlohmann::json& iface_array =
Sunitha Harish462023a2020-02-19 08:34:59 -06001676 asyncResp->res.jsonValue["Members"];
1677 iface_array = nlohmann::json::array();
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001678 auto& count = asyncResp->res.jsonValue["Members@odata.count"];
Sunitha Harish462023a2020-02-19 08:34:59 -06001679 count = 0;
Ed Tanouscb13a392020-07-25 19:02:03 +00001680 iface_array.push_back(
1681 {{"@odata.id", "/redfish/v1/Systems/system"}});
1682 if (!ec)
Sunitha Harish462023a2020-02-19 08:34:59 -06001683 {
Ed Tanouscb13a392020-07-25 19:02:03 +00001684 BMCWEB_LOG_DEBUG << "Hypervisor is available";
Sunitha Harish462023a2020-02-19 08:34:59 -06001685 iface_array.push_back(
Ed Tanouscb13a392020-07-25 19:02:03 +00001686 {{"@odata.id", "/redfish/v1/Systems/hypervisor"}});
Sunitha Harish462023a2020-02-19 08:34:59 -06001687 count = iface_array.size();
1688 return;
1689 }
Sunitha Harish462023a2020-02-19 08:34:59 -06001690 },
Sunitha Harish8e651fb2020-06-17 06:06:25 -05001691 "xyz.openbmc_project.Settings",
1692 "/xyz/openbmc_project/network/hypervisor",
Sunitha Harish462023a2020-02-19 08:34:59 -06001693 "org.freedesktop.DBus.Properties", "Get",
1694 "xyz.openbmc_project.Network.SystemConfiguration", "HostName");
Ed Tanous1abe55e2018-09-05 08:30:59 -07001695 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001696};
1697
1698/**
Ed Tanouscc340dd2018-08-29 13:43:38 -07001699 * SystemActionsReset class supports handle POST method for Reset action.
1700 * The class retrieves and sends data directly to D-Bus.
1701 */
1702class SystemActionsReset : public Node
1703{
1704 public:
Ed Tanous52cc1122020-07-18 13:51:21 -07001705 SystemActionsReset(App& app) :
Ed Tanous029573d2019-02-01 10:57:49 -08001706 Node(app, "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/")
Ed Tanouscc340dd2018-08-29 13:43:38 -07001707 {
1708 entityPrivileges = {
1709 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1710 }
1711
1712 private:
1713 /**
1714 * Function handles POST method request.
1715 * Analyzes POST body message before sends Reset request data to D-Bus.
1716 */
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001717 void doPost(crow::Response& res, const crow::Request& req,
Ed Tanouscb13a392020-07-25 19:02:03 +00001718 const std::vector<std::string>&) override
Ed Tanouscc340dd2018-08-29 13:43:38 -07001719 {
Ed Tanous9712f8a2018-09-21 13:38:49 -07001720 auto asyncResp = std::make_shared<AsyncResp>(res);
1721
1722 std::string resetType;
1723 if (!json_util::readJson(req, res, "ResetType", resetType))
Ed Tanouscc340dd2018-08-29 13:43:38 -07001724 {
1725 return;
1726 }
1727
Jason M. Billsd22c8392019-06-03 13:59:03 -07001728 // Get the command and host vs. chassis
Ed Tanous9712f8a2018-09-21 13:38:49 -07001729 std::string command;
Jason M. Billsd22c8392019-06-03 13:59:03 -07001730 bool hostCommand;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001731 if (resetType == "On")
1732 {
1733 command = "xyz.openbmc_project.State.Host.Transition.On";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001734 hostCommand = true;
1735 }
1736 else if (resetType == "ForceOff")
1737 {
1738 command = "xyz.openbmc_project.State.Chassis.Transition.Off";
1739 hostCommand = false;
1740 }
1741 else if (resetType == "ForceOn")
1742 {
1743 command = "xyz.openbmc_project.State.Host.Transition.On";
1744 hostCommand = true;
1745 }
1746 else if (resetType == "ForceRestart")
1747 {
Jason M. Bills86a08512020-02-04 13:15:49 -08001748 command =
1749 "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
1750 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001751 }
1752 else if (resetType == "GracefulShutdown")
1753 {
1754 command = "xyz.openbmc_project.State.Host.Transition.Off";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001755 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001756 }
1757 else if (resetType == "GracefulRestart")
1758 {
Jason M. Bills86a08512020-02-04 13:15:49 -08001759 command =
1760 "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001761 hostCommand = true;
1762 }
1763 else if (resetType == "PowerCycle")
1764 {
Jason M. Bills86a08512020-02-04 13:15:49 -08001765 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
1766 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001767 }
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001768 else if (resetType == "Nmi")
1769 {
1770 doNMI(asyncResp);
1771 return;
1772 }
Ed Tanous9712f8a2018-09-21 13:38:49 -07001773 else
1774 {
Jason M. Billsf12894f2018-10-09 12:45:45 -07001775 messages::actionParameterUnknown(res, "Reset", resetType);
Ed Tanous9712f8a2018-09-21 13:38:49 -07001776 return;
1777 }
1778
Jason M. Billsd22c8392019-06-03 13:59:03 -07001779 if (hostCommand)
1780 {
1781 crow::connections::systemBus->async_method_call(
1782 [asyncResp, resetType](const boost::system::error_code ec) {
1783 if (ec)
1784 {
1785 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1786 if (ec.value() == boost::asio::error::invalid_argument)
1787 {
1788 messages::actionParameterNotSupported(
1789 asyncResp->res, resetType, "Reset");
1790 }
1791 else
1792 {
1793 messages::internalError(asyncResp->res);
1794 }
1795 return;
1796 }
1797 messages::success(asyncResp->res);
1798 },
1799 "xyz.openbmc_project.State.Host",
1800 "/xyz/openbmc_project/state/host0",
1801 "org.freedesktop.DBus.Properties", "Set",
1802 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
1803 std::variant<std::string>{command});
1804 }
1805 else
1806 {
1807 crow::connections::systemBus->async_method_call(
1808 [asyncResp, resetType](const boost::system::error_code ec) {
1809 if (ec)
1810 {
1811 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1812 if (ec.value() == boost::asio::error::invalid_argument)
1813 {
1814 messages::actionParameterNotSupported(
1815 asyncResp->res, resetType, "Reset");
1816 }
1817 else
1818 {
1819 messages::internalError(asyncResp->res);
1820 }
1821 return;
1822 }
1823 messages::success(asyncResp->res);
1824 },
1825 "xyz.openbmc_project.State.Chassis",
1826 "/xyz/openbmc_project/state/chassis0",
1827 "org.freedesktop.DBus.Properties", "Set",
1828 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
1829 std::variant<std::string>{command});
1830 }
Ed Tanouscc340dd2018-08-29 13:43:38 -07001831 }
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001832 /**
1833 * Function transceives data with dbus directly.
1834 */
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001835 void doNMI(const std::shared_ptr<AsyncResp>& asyncResp)
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001836 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001837 constexpr char const* serviceName =
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001838 "xyz.openbmc_project.Control.Host.NMI";
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001839 constexpr char const* objectPath =
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001840 "/xyz/openbmc_project/control/host0/nmi";
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001841 constexpr char const* interfaceName =
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001842 "xyz.openbmc_project.Control.Host.NMI";
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001843 constexpr char const* method = "NMI";
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001844
1845 crow::connections::systemBus->async_method_call(
1846 [asyncResp](const boost::system::error_code ec) {
1847 if (ec)
1848 {
1849 BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
1850 messages::internalError(asyncResp->res);
1851 return;
1852 }
1853 messages::success(asyncResp->res);
1854 },
1855 serviceName, objectPath, interfaceName, method);
1856 }
Ed Tanouscc340dd2018-08-29 13:43:38 -07001857};
1858
1859/**
Ed Tanous66173382018-08-15 18:20:59 -07001860 * Systems derived class for delivering Computer Systems Schema.
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001861 */
Ed Tanous1abe55e2018-09-05 08:30:59 -07001862class Systems : public Node
1863{
1864 public:
1865 /*
1866 * Default Constructor
1867 */
Ed Tanous52cc1122020-07-18 13:51:21 -07001868 Systems(App& app) : Node(app, "/redfish/v1/Systems/system/")
Ed Tanous1abe55e2018-09-05 08:30:59 -07001869 {
Ed Tanous1abe55e2018-09-05 08:30:59 -07001870 entityPrivileges = {
1871 {boost::beast::http::verb::get, {{"Login"}}},
1872 {boost::beast::http::verb::head, {{"Login"}}},
1873 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1874 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1875 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1876 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001877 }
1878
Ed Tanous1abe55e2018-09-05 08:30:59 -07001879 private:
Ed Tanous1abe55e2018-09-05 08:30:59 -07001880 /**
1881 * Functions triggers appropriate requests on DBus
1882 */
Ed Tanouscb13a392020-07-25 19:02:03 +00001883 void doGet(crow::Response& res, const crow::Request&,
1884 const std::vector<std::string>&) override
Ed Tanous1abe55e2018-09-05 08:30:59 -07001885 {
Gunnar Millsc0557e12020-06-30 11:26:20 -05001886 res.jsonValue["@odata.type"] = "#ComputerSystem.v1_12_0.ComputerSystem";
Gunnar Mills450a25c2020-04-14 21:34:07 -05001887 res.jsonValue["Name"] = "system";
Ed Tanous029573d2019-02-01 10:57:49 -08001888 res.jsonValue["Id"] = "system";
Ed Tanous0f74e642018-11-12 15:17:05 -08001889 res.jsonValue["SystemType"] = "Physical";
1890 res.jsonValue["Description"] = "Computer System";
Ed Tanous0f74e642018-11-12 15:17:05 -08001891 res.jsonValue["ProcessorSummary"]["Count"] = 0;
1892 res.jsonValue["ProcessorSummary"]["Status"]["State"] = "Disabled";
Cheng C Yang5fd7ba62019-11-28 15:58:08 +08001893 res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = uint64_t(0);
Ed Tanous0f74e642018-11-12 15:17:05 -08001894 res.jsonValue["MemorySummary"]["Status"]["State"] = "Disabled";
Ed Tanous029573d2019-02-01 10:57:49 -08001895 res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
Ed Tanous04a258f2018-10-15 08:00:41 -07001896
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001897 res.jsonValue["Processors"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001898 {"@odata.id", "/redfish/v1/Systems/system/Processors"}};
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001899 res.jsonValue["Memory"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001900 {"@odata.id", "/redfish/v1/Systems/system/Memory"}};
Nikhil Potadea25aecc2019-08-23 16:35:26 -07001901 res.jsonValue["Storage"] = {
1902 {"@odata.id", "/redfish/v1/Systems/system/Storage"}};
Ed Tanous029573d2019-02-01 10:57:49 -08001903
Ed Tanouscc340dd2018-08-29 13:43:38 -07001904 res.jsonValue["Actions"]["#ComputerSystem.Reset"] = {
1905 {"target",
Ed Tanous029573d2019-02-01 10:57:49 -08001906 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"},
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05301907 {"@Redfish.ActionInfo",
1908 "/redfish/v1/Systems/system/ResetActionInfo"}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001909
Jason M. Billsc4bf6372018-11-05 13:48:27 -08001910 res.jsonValue["LogServices"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001911 {"@odata.id", "/redfish/v1/Systems/system/LogServices"}};
Jason M. Billsc4bf6372018-11-05 13:48:27 -08001912
Carol Wangd82a3ac2019-11-21 13:56:38 +08001913 res.jsonValue["Bios"] = {
1914 {"@odata.id", "/redfish/v1/Systems/system/Bios"}};
1915
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001916 res.jsonValue["Links"]["ManagedBy"] = {
1917 {{"@odata.id", "/redfish/v1/Managers/bmc"}}};
1918
1919 res.jsonValue["Status"] = {
1920 {"Health", "OK"},
1921 {"State", "Enabled"},
1922 };
Ed Tanousa0803ef2018-08-29 13:29:23 -07001923 auto asyncResp = std::make_shared<AsyncResp>(res);
Ed Tanous1abe55e2018-09-05 08:30:59 -07001924
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001925 constexpr const std::array<const char*, 4> inventoryForSystems = {
James Feistb49ac872019-05-21 15:12:01 -07001926 "xyz.openbmc_project.Inventory.Item.Dimm",
James Feist2ad9c2f2019-10-29 16:26:48 -07001927 "xyz.openbmc_project.Inventory.Item.Cpu",
James Feiste284a7c2019-11-20 16:20:23 -08001928 "xyz.openbmc_project.Inventory.Item.Drive",
1929 "xyz.openbmc_project.Inventory.Item.StorageController"};
James Feistb49ac872019-05-21 15:12:01 -07001930
1931 auto health = std::make_shared<HealthPopulate>(asyncResp);
1932 crow::connections::systemBus->async_method_call(
1933 [health](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001934 std::vector<std::string>& resp) {
James Feistb49ac872019-05-21 15:12:01 -07001935 if (ec)
1936 {
1937 // no inventory
1938 return;
1939 }
1940
1941 health->inventory = std::move(resp);
1942 },
1943 "xyz.openbmc_project.ObjectMapper",
1944 "/xyz/openbmc_project/object_mapper",
1945 "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", "/",
1946 int32_t(0), inventoryForSystems);
1947
1948 health->populate();
1949
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001950 getMainChassisId(asyncResp, [](const std::string& chassisId,
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001951 std::shared_ptr<AsyncResp> aRsp) {
1952 aRsp->res.jsonValue["Links"]["Chassis"] = {
1953 {{"@odata.id", "/redfish/v1/Chassis/" + chassisId}}};
1954 });
AppaRao Pulia3002222019-11-12 21:32:59 +05301955
1956 getIndicatorLedState(asyncResp);
James Feist5bc2dc82019-10-22 14:33:16 -07001957 getComputerSystem(asyncResp, health);
Ed Tanous6c34de42018-08-29 13:37:36 -07001958 getHostState(asyncResp);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301959 getBootProperties(asyncResp);
Jason M. Billsadbe1922019-10-14 15:44:35 -07001960 getPCIeDeviceList(asyncResp, "PCIeDevices");
Yong Li51709ff2019-09-30 14:13:04 +08001961 getHostWatchdogTimer(asyncResp);
George Liuc6a620f2020-04-10 17:18:11 +08001962 getPowerRestorePolicy(asyncResp);
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001963 getAutomaticRetry(asyncResp);
Gunnar Millsc0557e12020-06-30 11:26:20 -05001964 getLastResetTime(asyncResp);
AppaRao Pulia6349912019-10-18 17:16:08 +05301965#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1966 getProvisioningStatus(asyncResp);
1967#endif
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001968 }
1969
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001970 void doPatch(crow::Response& res, const crow::Request& req,
Ed Tanouscb13a392020-07-25 19:02:03 +00001971 const std::vector<std::string>&) override
Ed Tanous1abe55e2018-09-05 08:30:59 -07001972 {
Santosh Puranikcde19e52019-02-20 00:10:56 +05301973 std::optional<std::string> indicatorLed;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301974 std::optional<nlohmann::json> bootProps;
Yong Lic45f0082019-10-10 14:19:01 +08001975 std::optional<nlohmann::json> wdtTimerProps;
George Liuc6a620f2020-04-10 17:18:11 +08001976 std::optional<std::string> powerRestorePolicy;
Santosh Puranik41352c22019-07-03 05:35:49 -05001977 auto asyncResp = std::make_shared<AsyncResp>(res);
1978
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001979 if (!json_util::readJson(req, res, "IndicatorLED", indicatorLed, "Boot",
George Liuc6a620f2020-04-10 17:18:11 +08001980 bootProps, "WatchdogTimer", wdtTimerProps,
1981 "PowerRestorePolicy", powerRestorePolicy))
Ed Tanous66173382018-08-15 18:20:59 -07001982 {
Ed Tanous9712f8a2018-09-21 13:38:49 -07001983 return;
1984 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301985
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001986 res.result(boost::beast::http::status::no_content);
Yong Lic45f0082019-10-10 14:19:01 +08001987
1988 if (wdtTimerProps)
1989 {
1990 std::optional<bool> wdtEnable;
1991 std::optional<std::string> wdtTimeOutAction;
1992
1993 if (!json_util::readJson(*wdtTimerProps, asyncResp->res,
1994 "FunctionEnabled", wdtEnable,
1995 "TimeoutAction", wdtTimeOutAction))
1996 {
1997 return;
1998 }
1999 setWDTProperties(asyncResp, std::move(wdtEnable),
2000 std::move(wdtTimeOutAction));
2001 }
2002
Santosh Puranik491d8ee2019-02-06 19:46:56 +05302003 if (bootProps)
2004 {
2005 std::optional<std::string> bootSource;
2006 std::optional<std::string> bootEnable;
Gunnar Mills69f35302020-05-17 16:06:31 -05002007 std::optional<std::string> automaticRetryConfig;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05302008
Gunnar Mills69f35302020-05-17 16:06:31 -05002009 if (!json_util::readJson(
2010 *bootProps, asyncResp->res, "BootSourceOverrideTarget",
2011 bootSource, "BootSourceOverrideEnabled", bootEnable,
2012 "AutomaticRetryConfig", automaticRetryConfig))
Santosh Puranik491d8ee2019-02-06 19:46:56 +05302013 {
2014 return;
2015 }
Gunnar Mills69f35302020-05-17 16:06:31 -05002016 if (bootSource || bootEnable)
2017 {
2018 setBootSourceProperties(asyncResp, std::move(bootSource),
2019 std::move(bootEnable));
2020 }
2021 if (automaticRetryConfig)
2022 {
2023 setAutomaticRetry(asyncResp, std::move(*automaticRetryConfig));
2024 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05302025 }
Johnathan Mantey265c1602019-08-08 11:02:51 -07002026
Ed Tanous9712f8a2018-09-21 13:38:49 -07002027 if (indicatorLed)
2028 {
AppaRao Pulia3002222019-11-12 21:32:59 +05302029 setIndicatorLedState(asyncResp, std::move(*indicatorLed));
Ed Tanous1abe55e2018-09-05 08:30:59 -07002030 }
George Liuc6a620f2020-04-10 17:18:11 +08002031
2032 if (powerRestorePolicy)
2033 {
2034 setPowerRestorePolicy(asyncResp, std::move(*powerRestorePolicy));
2035 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002036 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002037};
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05302038
2039/**
2040 * SystemResetActionInfo derived class for delivering Computer Systems
2041 * ResetType AllowableValues using ResetInfo schema.
2042 */
2043class SystemResetActionInfo : public Node
2044{
2045 public:
2046 /*
2047 * Default Constructor
2048 */
Ed Tanous52cc1122020-07-18 13:51:21 -07002049 SystemResetActionInfo(App& app) :
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05302050 Node(app, "/redfish/v1/Systems/system/ResetActionInfo/")
2051 {
2052 entityPrivileges = {
2053 {boost::beast::http::verb::get, {{"Login"}}},
2054 {boost::beast::http::verb::head, {{"Login"}}},
2055 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
2056 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
2057 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
2058 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
2059 }
2060
2061 private:
2062 /**
2063 * Functions triggers appropriate requests on DBus
2064 */
Ed Tanouscb13a392020-07-25 19:02:03 +00002065 void doGet(crow::Response& res, const crow::Request&,
2066 const std::vector<std::string>&) override
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05302067 {
2068 res.jsonValue = {
2069 {"@odata.type", "#ActionInfo.v1_1_2.ActionInfo"},
2070 {"@odata.id", "/redfish/v1/Systems/system/ResetActionInfo"},
2071 {"Name", "Reset Action Info"},
2072 {"Id", "ResetActionInfo"},
2073 {"Parameters",
2074 {{{"Name", "ResetType"},
2075 {"Required", true},
2076 {"DataType", "String"},
2077 {"AllowableValues",
2078 {"On", "ForceOff", "ForceOn", "ForceRestart", "GracefulRestart",
2079 "GracefulShutdown", "PowerCycle", "Nmi"}}}}}};
2080 res.end();
2081 }
2082};
Ed Tanous1abe55e2018-09-05 08:30:59 -07002083} // namespace redfish