blob: 9f304b09934d1e89c78060dda0a8c8b12456eb9c [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 Tanousb5a76932020-09-29 16:16:58 -070041inline void updateDimmProperties(const std::shared_ptr<AsyncResp>& aResp,
Ed Tanous23a21a12020-07-25 04:45:05 +000042 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 Tanousb5a76932020-09-29 16:16:58 -070075inline void modifyCpuPresenceState(const std::shared_ptr<AsyncResp>& aResp,
Ed Tanous23a21a12020-07-25 04:45:05 +000076 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
Ed Tanousb5a76932020-09-29 16:16:58 -0700111 modifyCpuFunctionalState(const std::shared_ptr<AsyncResp>& aResp,
Ed Tanous23a21a12020-07-25 04:45:05 +0000112 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 Tanousb5a76932020-09-29 16:16:58 -0700147inline void
148 getComputerSystem(const std::shared_ptr<AsyncResp>& aResp,
149 const std::shared_ptr<HealthPopulate>& systemHealth)
Ed Tanous6c34de42018-08-29 13:37:36 -0700150{
Ed Tanous6c34de42018-08-29 13:37:36 -0700151 BMCWEB_LOG_DEBUG << "Get available system components.";
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500152
Ed Tanous6c34de42018-08-29 13:37:36 -0700153 crow::connections::systemBus->async_method_call(
James Feist5bc2dc82019-10-22 14:33:16 -0700154 [aResp, systemHealth](
Ed Tanous6c34de42018-08-29 13:37:36 -0700155 const boost::system::error_code ec,
156 const std::vector<std::pair<
157 std::string,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500158 std::vector<std::pair<std::string, std::vector<std::string>>>>>&
159 subtree) {
Ed Tanous6c34de42018-08-29 13:37:36 -0700160 if (ec)
161 {
162 BMCWEB_LOG_DEBUG << "DBUS response error";
Jason M. Billsf12894f2018-10-09 12:45:45 -0700163 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700164 return;
165 }
Ed Tanous6c34de42018-08-29 13:37:36 -0700166 // Iterate over all retrieved ObjectPaths.
167 for (const std::pair<std::string,
168 std::vector<std::pair<
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500169 std::string, std::vector<std::string>>>>&
170 object : subtree)
Ed Tanous6c34de42018-08-29 13:37:36 -0700171 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500172 const std::string& path = object.first;
Ed Tanous6c34de42018-08-29 13:37:36 -0700173 BMCWEB_LOG_DEBUG << "Got path: " << path;
174 const std::vector<
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500175 std::pair<std::string, std::vector<std::string>>>&
176 connectionNames = object.second;
Ed Tanous6c34de42018-08-29 13:37:36 -0700177 if (connectionNames.size() < 1)
178 {
179 continue;
180 }
Ed Tanous029573d2019-02-01 10:57:49 -0800181
James Feist5bc2dc82019-10-22 14:33:16 -0700182 auto memoryHealth = std::make_shared<HealthPopulate>(
183 aResp, aResp->res.jsonValue["MemorySummary"]["Status"]);
184
185 auto cpuHealth = std::make_shared<HealthPopulate>(
186 aResp, aResp->res.jsonValue["ProcessorSummary"]["Status"]);
187
188 systemHealth->children.emplace_back(memoryHealth);
189 systemHealth->children.emplace_back(cpuHealth);
190
Ed Tanous029573d2019-02-01 10:57:49 -0800191 // This is not system, so check if it's cpu, dimm, UUID or
192 // BiosVer
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500193 for (const auto& connection : connectionNames)
Ed Tanous6c34de42018-08-29 13:37:36 -0700194 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500195 for (const auto& interfaceName : connection.second)
Ed Tanous6c34de42018-08-29 13:37:36 -0700196 {
Ed Tanous029573d2019-02-01 10:57:49 -0800197 if (interfaceName ==
198 "xyz.openbmc_project.Inventory.Item.Dimm")
Ed Tanous6c34de42018-08-29 13:37:36 -0700199 {
Ed Tanous029573d2019-02-01 10:57:49 -0800200 BMCWEB_LOG_DEBUG
201 << "Found Dimm, now get its properties.";
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500202
Ed Tanous029573d2019-02-01 10:57:49 -0800203 crow::connections::systemBus->async_method_call(
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500204 [aResp, service{connection.first},
205 path(std::move(path))](
Ed Tanouscb13a392020-07-25 19:02:03 +0000206 const boost::system::error_code ec2,
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500207 const std::vector<
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500208 std::pair<std::string, VariantType>>&
209 properties) {
Ed Tanouscb13a392020-07-25 19:02:03 +0000210 if (ec2)
Ed Tanous029573d2019-02-01 10:57:49 -0800211 {
212 BMCWEB_LOG_ERROR
Ed Tanouscb13a392020-07-25 19:02:03 +0000213 << "DBUS response error " << ec2;
Ed Tanous029573d2019-02-01 10:57:49 -0800214 messages::internalError(aResp->res);
215 return;
216 }
217 BMCWEB_LOG_DEBUG << "Got "
218 << properties.size()
Gunnar Mills698654b2019-10-16 13:17:37 -0500219 << " Dimm properties.";
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500220
221 if (properties.size() > 0)
Ed Tanous029573d2019-02-01 10:57:49 -0800222 {
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500223 for (const std::pair<std::string,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500224 VariantType>&
225 property : properties)
Ed Tanous6c34de42018-08-29 13:37:36 -0700226 {
Cheng C Yang5fd7ba62019-11-28 15:58:08 +0800227 if (property.first !=
228 "MemorySizeInKB")
Ed Tanous6c34de42018-08-29 13:37:36 -0700229 {
Cheng C Yang5fd7ba62019-11-28 15:58:08 +0800230 continue;
Ed Tanous6c34de42018-08-29 13:37:36 -0700231 }
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500232 const uint32_t* value =
Patrick Williams8d78b7a2020-05-13 11:24:20 -0500233 std::get_if<uint32_t>(
234 &property.second);
Cheng C Yang5fd7ba62019-11-28 15:58:08 +0800235 if (value == nullptr)
236 {
237 BMCWEB_LOG_DEBUG
238 << "Find incorrect type of "
239 "MemorySize";
240 continue;
241 }
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500242 nlohmann::json& totalMemory =
Cheng C Yang5fd7ba62019-11-28 15:58:08 +0800243 aResp->res
244 .jsonValue["MemorySummar"
245 "y"]
246 ["TotalSystemMe"
247 "moryGiB"];
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500248 uint64_t* preValue =
Cheng C Yang5fd7ba62019-11-28 15:58:08 +0800249 totalMemory
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500250 .get_ptr<uint64_t*>();
Cheng C Yang5fd7ba62019-11-28 15:58:08 +0800251 if (preValue == nullptr)
252 {
253 continue;
254 }
255 aResp->res
256 .jsonValue["MemorySummary"]
257 ["TotalSystemMemoryGi"
258 "B"] =
259 *value / (1024 * 1024) +
260 *preValue;
261 aResp->res
262 .jsonValue["MemorySummary"]
263 ["Status"]["State"] =
264 "Enabled";
Ed Tanous6c34de42018-08-29 13:37:36 -0700265 }
Ed Tanous029573d2019-02-01 10:57:49 -0800266 }
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500267 else
268 {
269 auto getDimmProperties =
270 [aResp](
271 const boost::system::error_code
Ed Tanouscb13a392020-07-25 19:02:03 +0000272 ec3,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500273 const std::variant<bool>&
274 dimmState) {
Ed Tanouscb13a392020-07-25 19:02:03 +0000275 if (ec3)
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500276 {
277 BMCWEB_LOG_ERROR
278 << "DBUS response "
279 "error "
Ed Tanouscb13a392020-07-25 19:02:03 +0000280 << ec3;
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500281 return;
282 }
283 updateDimmProperties(aResp,
284 dimmState);
285 };
286 crow::connections::systemBus
287 ->async_method_call(
288 std::move(getDimmProperties),
289 service, path,
290 "org.freedesktop.DBus."
291 "Properties",
292 "Get",
293 "xyz.openbmc_project.State."
294 "Decorator.OperationalStatus",
295 "Functional");
296 }
Ed Tanous029573d2019-02-01 10:57:49 -0800297 },
298 connection.first, path,
299 "org.freedesktop.DBus.Properties", "GetAll",
300 "xyz.openbmc_project.Inventory.Item.Dimm");
James Feist5bc2dc82019-10-22 14:33:16 -0700301
302 memoryHealth->inventory.emplace_back(path);
Ed Tanous029573d2019-02-01 10:57:49 -0800303 }
304 else if (interfaceName ==
305 "xyz.openbmc_project.Inventory.Item.Cpu")
306 {
307 BMCWEB_LOG_DEBUG
308 << "Found Cpu, now get its properties.";
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500309
Ed Tanous029573d2019-02-01 10:57:49 -0800310 crow::connections::systemBus->async_method_call(
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500311 [aResp, service{connection.first},
312 path(std::move(path))](
Ed Tanouscb13a392020-07-25 19:02:03 +0000313 const boost::system::error_code ec2,
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500314 const std::vector<
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500315 std::pair<std::string, VariantType>>&
316 properties) {
Ed Tanouscb13a392020-07-25 19:02:03 +0000317 if (ec2)
Ed Tanous029573d2019-02-01 10:57:49 -0800318 {
319 BMCWEB_LOG_ERROR
Ed Tanouscb13a392020-07-25 19:02:03 +0000320 << "DBUS response error " << ec2;
Ed Tanous029573d2019-02-01 10:57:49 -0800321 messages::internalError(aResp->res);
322 return;
323 }
324 BMCWEB_LOG_DEBUG << "Got "
325 << properties.size()
Gunnar Mills698654b2019-10-16 13:17:37 -0500326 << " Cpu properties.";
Ed Tanous04a258f2018-10-15 08:00:41 -0700327
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500328 if (properties.size() > 0)
329 {
Zhikui Ren9cf21522020-09-10 11:13:14 -0700330 const uint64_t* processorId = nullptr;
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700331 const std::string* procFamily = nullptr;
332 nlohmann::json& procSummary =
333 aResp->res.jsonValue["ProcessorSumm"
334 "ary"];
335 nlohmann::json& procCount =
336 procSummary["Count"];
337
338 auto procCountPtr = procCount.get_ptr<
339 nlohmann::json::
340 number_integer_t*>();
341 if (procCountPtr == nullptr)
342 {
343 messages::internalError(aResp->res);
344 return;
345 }
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500346 for (const auto& property : properties)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500347 {
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700348
Zhikui Ren9cf21522020-09-10 11:13:14 -0700349 if (property.first == "Id")
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700350 {
351 processorId =
Zhikui Ren9cf21522020-09-10 11:13:14 -0700352 std::get_if<uint64_t>(
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700353 &property.second);
354 if (nullptr != procFamily)
Ed Tanous3174e4d2020-10-07 11:41:22 -0700355 {
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700356 break;
Ed Tanous3174e4d2020-10-07 11:41:22 -0700357 }
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700358 continue;
359 }
360
Zhikui Ren9cf21522020-09-10 11:13:14 -0700361 if (property.first == "Family")
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500362 {
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700363 procFamily =
Patrick Williams8d78b7a2020-05-13 11:24:20 -0500364 std::get_if<std::string>(
365 &property.second);
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700366 if (nullptr != processorId)
Ed Tanous3174e4d2020-10-07 11:41:22 -0700367 {
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700368 break;
Ed Tanous3174e4d2020-10-07 11:41:22 -0700369 }
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700370 continue;
371 }
372 }
James Feistb4b95952019-12-05 15:01:55 -0800373
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700374 if (procFamily != nullptr &&
375 processorId != nullptr)
376 {
377 if (procCountPtr != nullptr &&
378 *processorId != 0)
379 {
380 *procCountPtr += 1;
381 procSummary["Status"]["State"] =
382 "Enabled";
383
384 procSummary["Model"] =
385 *procFamily;
Ed Tanous6c34de42018-08-29 13:37:36 -0700386 }
387 }
Ed Tanous029573d2019-02-01 10:57:49 -0800388 }
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500389 else
390 {
391 auto getCpuPresenceState =
392 [aResp](
393 const boost::system::error_code
Ed Tanouscb13a392020-07-25 19:02:03 +0000394 ec3,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500395 const std::variant<bool>&
396 cpuPresenceCheck) {
Ed Tanouscb13a392020-07-25 19:02:03 +0000397 if (ec3)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500398 {
399 BMCWEB_LOG_ERROR
400 << "DBUS response "
401 "error "
Ed Tanouscb13a392020-07-25 19:02:03 +0000402 << ec3;
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500403 return;
404 }
405 modifyCpuPresenceState(
406 aResp, cpuPresenceCheck);
407 };
408
409 auto getCpuFunctionalState =
410 [aResp](
411 const boost::system::error_code
Ed Tanouscb13a392020-07-25 19:02:03 +0000412 ec3,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500413 const std::variant<bool>&
414 cpuFunctionalCheck) {
Ed Tanouscb13a392020-07-25 19:02:03 +0000415 if (ec3)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500416 {
417 BMCWEB_LOG_ERROR
418 << "DBUS response "
419 "error "
Ed Tanouscb13a392020-07-25 19:02:03 +0000420 << ec3;
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500421 return;
422 }
423 modifyCpuFunctionalState(
424 aResp, cpuFunctionalCheck);
425 };
426 // Get the Presence of CPU
427 crow::connections::systemBus
428 ->async_method_call(
429 std::move(getCpuPresenceState),
430 service, path,
431 "org.freedesktop.DBus."
432 "Properties",
433 "Get",
434 "xyz.openbmc_project.Inventory."
435 "Item",
436 "Present");
437
438 // Get the Functional State
439 crow::connections::systemBus
440 ->async_method_call(
441 std::move(
442 getCpuFunctionalState),
443 service, path,
444 "org.freedesktop.DBus."
445 "Properties",
446 "Get",
447 "xyz.openbmc_project.State."
448 "Decorator."
449 "OperationalStatus",
450 "Functional");
451
452 // Get the MODEL from
453 // xyz.openbmc_project.Inventory.Decorator.Asset
454 // support it later as Model is Empty
455 // currently.
456 }
Ed Tanous029573d2019-02-01 10:57:49 -0800457 },
458 connection.first, path,
459 "org.freedesktop.DBus.Properties", "GetAll",
460 "xyz.openbmc_project.Inventory.Item.Cpu");
James Feist5bc2dc82019-10-22 14:33:16 -0700461
462 cpuHealth->inventory.emplace_back(path);
Ed Tanous029573d2019-02-01 10:57:49 -0800463 }
464 else if (interfaceName ==
465 "xyz.openbmc_project.Common.UUID")
466 {
467 BMCWEB_LOG_DEBUG
468 << "Found UUID, now get its properties.";
469 crow::connections::systemBus->async_method_call(
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500470 [aResp](
Ed Tanouscb13a392020-07-25 19:02:03 +0000471 const boost::system::error_code ec3,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500472 const std::vector<
473 std::pair<std::string, VariantType>>&
474 properties) {
Ed Tanouscb13a392020-07-25 19:02:03 +0000475 if (ec3)
Ed Tanous029573d2019-02-01 10:57:49 -0800476 {
477 BMCWEB_LOG_DEBUG
Ed Tanouscb13a392020-07-25 19:02:03 +0000478 << "DBUS response error " << ec3;
Ed Tanous029573d2019-02-01 10:57:49 -0800479 messages::internalError(aResp->res);
480 return;
481 }
482 BMCWEB_LOG_DEBUG << "Got "
483 << properties.size()
Gunnar Mills698654b2019-10-16 13:17:37 -0500484 << " UUID properties.";
Ed Tanous029573d2019-02-01 10:57:49 -0800485 for (const std::pair<std::string,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500486 VariantType>&
487 property : properties)
Ed Tanous029573d2019-02-01 10:57:49 -0800488 {
Ed Tanous029573d2019-02-01 10:57:49 -0800489 if (property.first == "UUID")
490 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500491 const std::string* value =
Patrick Williams8d78b7a2020-05-13 11:24:20 -0500492 std::get_if<std::string>(
493 &property.second);
Ed Tanous04a258f2018-10-15 08:00:41 -0700494
Ed Tanous029573d2019-02-01 10:57:49 -0800495 if (value != nullptr)
496 {
497 std::string valueStr = *value;
498 if (valueStr.size() == 32)
Ed Tanous6c34de42018-08-29 13:37:36 -0700499 {
Ed Tanous029573d2019-02-01 10:57:49 -0800500 valueStr.insert(8, 1, '-');
501 valueStr.insert(13, 1, '-');
502 valueStr.insert(18, 1, '-');
503 valueStr.insert(23, 1, '-');
Ed Tanous6c34de42018-08-29 13:37:36 -0700504 }
Ed Tanous029573d2019-02-01 10:57:49 -0800505 BMCWEB_LOG_DEBUG << "UUID = "
506 << valueStr;
507 aResp->res.jsonValue["UUID"] =
508 valueStr;
Ed Tanous6c34de42018-08-29 13:37:36 -0700509 }
510 }
Ed Tanous029573d2019-02-01 10:57:49 -0800511 }
512 },
513 connection.first, path,
514 "org.freedesktop.DBus.Properties", "GetAll",
515 "xyz.openbmc_project.Common.UUID");
516 }
517 else if (interfaceName ==
518 "xyz.openbmc_project.Inventory.Item.System")
519 {
520 crow::connections::systemBus->async_method_call(
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500521 [aResp](
Ed Tanouscb13a392020-07-25 19:02:03 +0000522 const boost::system::error_code ec2,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500523 const std::vector<
524 std::pair<std::string, VariantType>>&
525 propertiesList) {
Ed Tanouscb13a392020-07-25 19:02:03 +0000526 if (ec2)
Ed Tanous029573d2019-02-01 10:57:49 -0800527 {
James Feiste4a4b9a2019-06-20 14:08:07 -0700528 // doesn't have to include this
529 // interface
Ed Tanous029573d2019-02-01 10:57:49 -0800530 return;
531 }
Gunnar Mills698654b2019-10-16 13:17:37 -0500532 BMCWEB_LOG_DEBUG
533 << "Got " << propertiesList.size()
534 << " properties for system";
Ed Tanous029573d2019-02-01 10:57:49 -0800535 for (const std::pair<std::string,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500536 VariantType>&
537 property : propertiesList)
Ed Tanous029573d2019-02-01 10:57:49 -0800538 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500539 const std::string& propertyName =
beccabroekfc5afcf2019-03-05 14:35:15 -0600540 property.first;
541 if ((propertyName == "PartNumber") ||
542 (propertyName == "SerialNumber") ||
543 (propertyName == "Manufacturer") ||
544 (propertyName == "Model"))
Ed Tanous029573d2019-02-01 10:57:49 -0800545 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500546 const std::string* value =
beccabroekfc5afcf2019-03-05 14:35:15 -0600547 std::get_if<std::string>(
548 &property.second);
549 if (value != nullptr)
550 {
551 aResp->res
552 .jsonValue[propertyName] =
553 *value;
554 }
Ed Tanous029573d2019-02-01 10:57:49 -0800555 }
556 }
Gunnar Millsc1e236a2020-04-14 21:36:33 -0500557
Andrew Geisslercb7e1e72019-02-19 13:05:38 -0600558 // Grab the bios version
Gunnar Millsf97ddba2020-08-20 15:57:40 -0500559 fw_util::populateFirmwareInformation(
Andrew Geisslercb7e1e72019-02-19 13:05:38 -0600560 aResp, fw_util::biosPurpose,
Gunnar Mills72d566d2020-07-21 12:44:00 -0500561 "BiosVersion", false);
Ed Tanous029573d2019-02-01 10:57:49 -0800562 },
563 connection.first, path,
564 "org.freedesktop.DBus.Properties", "GetAll",
565 "xyz.openbmc_project.Inventory.Decorator."
566 "Asset");
James Feiste4a4b9a2019-06-20 14:08:07 -0700567
568 crow::connections::systemBus->async_method_call(
569 [aResp](
Ed Tanouscb13a392020-07-25 19:02:03 +0000570 const boost::system::error_code ec2,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500571 const std::variant<std::string>& property) {
Ed Tanouscb13a392020-07-25 19:02:03 +0000572 if (ec2)
James Feiste4a4b9a2019-06-20 14:08:07 -0700573 {
574 // doesn't have to include this
575 // interface
576 return;
577 }
578
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500579 const std::string* value =
James Feiste4a4b9a2019-06-20 14:08:07 -0700580 std::get_if<std::string>(&property);
581 if (value != nullptr)
582 {
583 aResp->res.jsonValue["AssetTag"] =
584 *value;
585 }
586 },
587 connection.first, path,
588 "org.freedesktop.DBus.Properties", "Get",
589 "xyz.openbmc_project.Inventory.Decorator."
590 "AssetTag",
591 "AssetTag");
Ed Tanous6c34de42018-08-29 13:37:36 -0700592 }
593 }
594 }
595 }
Ed Tanous6c34de42018-08-29 13:37:36 -0700596 },
597 "xyz.openbmc_project.ObjectMapper",
598 "/xyz/openbmc_project/object_mapper",
599 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
Ed Tanous66173382018-08-15 18:20:59 -0700600 "/xyz/openbmc_project/inventory", int32_t(0),
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500601 std::array<const char*, 5>{
Ed Tanous66173382018-08-15 18:20:59 -0700602 "xyz.openbmc_project.Inventory.Decorator.Asset",
603 "xyz.openbmc_project.Inventory.Item.Cpu",
604 "xyz.openbmc_project.Inventory.Item.Dimm",
605 "xyz.openbmc_project.Inventory.Item.System",
606 "xyz.openbmc_project.Common.UUID",
607 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700608}
609
610/**
Ed Tanous6c34de42018-08-29 13:37:36 -0700611 * @brief Retrieves host state properties over dbus
612 *
613 * @param[in] aResp Shared pointer for completing asynchronous calls.
614 *
615 * @return None.
616 */
Ed Tanousb5a76932020-09-29 16:16:58 -0700617inline void getHostState(const std::shared_ptr<AsyncResp>& aResp)
Ed Tanous6c34de42018-08-29 13:37:36 -0700618{
619 BMCWEB_LOG_DEBUG << "Get host information.";
620 crow::connections::systemBus->async_method_call(
Jennifer Leec5d03ff2019-03-08 15:42:58 -0800621 [aResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500622 const std::variant<std::string>& hostState) {
Ed Tanous6c34de42018-08-29 13:37:36 -0700623 if (ec)
624 {
625 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700626 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700627 return;
628 }
Ed Tanous66173382018-08-15 18:20:59 -0700629
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500630 const std::string* s = std::get_if<std::string>(&hostState);
Ed Tanous66173382018-08-15 18:20:59 -0700631 BMCWEB_LOG_DEBUG << "Host state: " << *s;
632 if (s != nullptr)
Ed Tanous6c34de42018-08-29 13:37:36 -0700633 {
Ed Tanous66173382018-08-15 18:20:59 -0700634 // Verify Host State
Andrew Geissler94732662019-01-08 19:32:16 -0800635 if (*s == "xyz.openbmc_project.State.Host.HostState.Running")
Ed Tanous6c34de42018-08-29 13:37:36 -0700636 {
Ed Tanous66173382018-08-15 18:20:59 -0700637 aResp->res.jsonValue["PowerState"] = "On";
638 aResp->res.jsonValue["Status"]["State"] = "Enabled";
639 }
Andrew Geissler83935af2020-02-13 10:24:53 -0600640 else if (*s == "xyz.openbmc_project.State.Host.HostState."
Gunnar Mills8c888602020-05-01 14:25:09 -0500641 "Quiesced")
642 {
643 aResp->res.jsonValue["PowerState"] = "On";
644 aResp->res.jsonValue["Status"]["State"] = "Quiesced";
645 }
646 else if (*s == "xyz.openbmc_project.State.Host.HostState."
Andrew Geissler83935af2020-02-13 10:24:53 -0600647 "DiagnosticMode")
648 {
649 aResp->res.jsonValue["PowerState"] = "On";
650 aResp->res.jsonValue["Status"]["State"] = "InTest";
651 }
Ed Tanous66173382018-08-15 18:20:59 -0700652 else
653 {
654 aResp->res.jsonValue["PowerState"] = "Off";
655 aResp->res.jsonValue["Status"]["State"] = "Disabled";
Ed Tanous6c34de42018-08-29 13:37:36 -0700656 }
657 }
658 },
659 "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
Ed Tanous66173382018-08-15 18:20:59 -0700660 "org.freedesktop.DBus.Properties", "Get",
661 "xyz.openbmc_project.State.Host", "CurrentHostState");
Ed Tanous6c34de42018-08-29 13:37:36 -0700662}
663
664/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500665 * @brief Translates boot source DBUS property value to redfish.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530666 *
667 * @param[in] dbusSource The boot source in DBUS speak.
668 *
669 * @return Returns as a string, the boot source in Redfish terms. If translation
670 * cannot be done, returns an empty string.
671 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000672inline std::string dbusToRfBootSource(const std::string& dbusSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530673{
674 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
675 {
676 return "None";
677 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700678 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530679 {
680 return "Hdd";
681 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700682 if (dbusSource ==
683 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530684 {
685 return "Cd";
686 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700687 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530688 {
689 return "Pxe";
690 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700691 if (dbusSource ==
692 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700693 {
694 return "Usb";
695 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700696 return "";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530697}
698
699/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500700 * @brief Translates boot mode DBUS property value to redfish.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530701 *
702 * @param[in] dbusMode The boot mode in DBUS speak.
703 *
704 * @return Returns as a string, the boot mode in Redfish terms. If translation
705 * cannot be done, returns an empty string.
706 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000707inline std::string dbusToRfBootMode(const std::string& dbusMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530708{
709 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
710 {
711 return "None";
712 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700713 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530714 {
715 return "Diags";
716 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700717 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530718 {
719 return "BiosSetup";
720 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700721 return "";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530722}
723
724/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500725 * @brief Translates boot source from Redfish to the DBus boot paths.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530726 *
727 * @param[in] rfSource The boot source in Redfish.
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700728 * @param[out] bootSource The DBus source
729 * @param[out] bootMode the DBus boot mode
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530730 *
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700731 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530732 */
Ed Tanousb5a76932020-09-29 16:16:58 -0700733inline int assignBootParameters(const std::shared_ptr<AsyncResp>& aResp,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500734 const std::string& rfSource,
735 std::string& bootSource, std::string& bootMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530736{
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700737 // The caller has initialized the bootSource and bootMode to:
738 // bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
739 // bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
740 // Only modify the bootSource/bootMode variable needed to achieve the
741 // desired boot action.
742
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530743 if (rfSource == "None")
744 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700745 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530746 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700747 if (rfSource == "Pxe")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530748 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700749 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
750 }
751 else if (rfSource == "Hdd")
752 {
753 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
754 }
755 else if (rfSource == "Diags")
756 {
757 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
758 }
759 else if (rfSource == "Cd")
760 {
761 bootSource =
762 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
763 }
764 else if (rfSource == "BiosSetup")
765 {
766 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530767 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700768 else if (rfSource == "Usb")
769 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700770 bootSource =
771 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700772 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530773 else
774 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700775 BMCWEB_LOG_DEBUG << "Invalid property value for "
776 "BootSourceOverrideTarget: "
777 << bootSource;
778 messages::propertyValueNotInList(aResp->res, rfSource,
779 "BootSourceTargetOverride");
780 return -1;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530781 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700782 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530783}
784
785/**
786 * @brief Retrieves boot mode over DBUS and fills out the response
787 *
788 * @param[in] aResp Shared pointer for generating response message.
789 * @param[in] bootDbusObj The dbus object to query for boot properties.
790 *
791 * @return None.
792 */
Ed Tanousb5a76932020-09-29 16:16:58 -0700793inline void getBootMode(const std::shared_ptr<AsyncResp>& aResp,
794 const std::string& bootDbusObj)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530795{
796 crow::connections::systemBus->async_method_call(
797 [aResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500798 const std::variant<std::string>& bootMode) {
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530799 if (ec)
800 {
801 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
802 messages::internalError(aResp->res);
803 return;
804 }
805
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500806 const std::string* bootModeStr =
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530807 std::get_if<std::string>(&bootMode);
808
809 if (!bootModeStr)
810 {
811 messages::internalError(aResp->res);
812 return;
813 }
814
815 BMCWEB_LOG_DEBUG << "Boot mode: " << *bootModeStr;
816
817 // TODO (Santosh): Do we need to support override mode?
818 aResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = "Legacy";
819 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget@Redfish."
820 "AllowableValues"] = {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700821 "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530822
823 if (*bootModeStr !=
824 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
825 {
826 auto rfMode = dbusToRfBootMode(*bootModeStr);
827 if (!rfMode.empty())
828 {
829 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
830 rfMode;
831 }
832 }
833
834 // If the BootSourceOverrideTarget is still "None" at the end,
835 // reset the BootSourceOverrideEnabled to indicate that
836 // overrides are disabled
837 if (aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] ==
838 "None")
839 {
840 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
841 "Disabled";
842 }
843 },
844 "xyz.openbmc_project.Settings", bootDbusObj,
845 "org.freedesktop.DBus.Properties", "Get",
846 "xyz.openbmc_project.Control.Boot.Mode", "BootMode");
847}
848
849/**
850 * @brief Retrieves boot source over DBUS
851 *
852 * @param[in] aResp Shared pointer for generating response message.
853 * @param[in] oneTimeEnable Boolean to indicate boot properties are one-time.
854 *
855 * @return None.
856 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000857inline void getBootSource(std::shared_ptr<AsyncResp> aResp, bool oneTimeEnabled)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530858{
859 std::string bootDbusObj =
860 oneTimeEnabled ? "/xyz/openbmc_project/control/host0/boot/one_time"
861 : "/xyz/openbmc_project/control/host0/boot";
862
863 BMCWEB_LOG_DEBUG << "Is one time: " << oneTimeEnabled;
864 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
865 (oneTimeEnabled) ? "Once" : "Continuous";
866
867 crow::connections::systemBus->async_method_call(
868 [aResp, bootDbusObj](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500869 const std::variant<std::string>& bootSource) {
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530870 if (ec)
871 {
872 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
873 messages::internalError(aResp->res);
874 return;
875 }
876
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500877 const std::string* bootSourceStr =
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530878 std::get_if<std::string>(&bootSource);
879
880 if (!bootSourceStr)
881 {
882 messages::internalError(aResp->res);
883 return;
884 }
885 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSourceStr;
886
887 auto rfSource = dbusToRfBootSource(*bootSourceStr);
888 if (!rfSource.empty())
889 {
890 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
891 rfSource;
892 }
893 },
894 "xyz.openbmc_project.Settings", bootDbusObj,
895 "org.freedesktop.DBus.Properties", "Get",
896 "xyz.openbmc_project.Control.Boot.Source", "BootSource");
897 getBootMode(std::move(aResp), std::move(bootDbusObj));
898}
899
900/**
901 * @brief Retrieves "One time" enabled setting over DBUS and calls function to
902 * get boot source and boot mode.
903 *
904 * @param[in] aResp Shared pointer for generating response message.
905 *
906 * @return None.
907 */
Ed Tanousb5a76932020-09-29 16:16:58 -0700908inline void getBootProperties(const std::shared_ptr<AsyncResp>& aResp)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530909{
910 BMCWEB_LOG_DEBUG << "Get boot information.";
911
912 crow::connections::systemBus->async_method_call(
Jennifer Leec5d03ff2019-03-08 15:42:58 -0800913 [aResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500914 const std::variant<bool>& oneTime) {
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530915 if (ec)
916 {
917 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
James Feist2a833c72019-07-19 10:17:13 -0700918 // not an error, don't have to have the interface
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530919 return;
920 }
921
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500922 const bool* oneTimePtr = std::get_if<bool>(&oneTime);
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530923
924 if (!oneTimePtr)
925 {
926 messages::internalError(aResp->res);
927 return;
928 }
929 getBootSource(aResp, *oneTimePtr);
930 },
931 "xyz.openbmc_project.Settings",
932 "/xyz/openbmc_project/control/host0/boot/one_time",
933 "org.freedesktop.DBus.Properties", "Get",
934 "xyz.openbmc_project.Object.Enable", "Enabled");
935}
936
937/**
Gunnar Millsc0557e12020-06-30 11:26:20 -0500938 * @brief Retrieves the Last Reset Time
939 *
940 * "Reset" is an overloaded term in Redfish, "Reset" includes power on
941 * and power off. Even though this is the "system" Redfish object look at the
942 * chassis D-Bus interface for the LastStateChangeTime since this has the
943 * last power operation time.
944 *
945 * @param[in] aResp Shared pointer for generating response message.
946 *
947 * @return None.
948 */
Ed Tanousb5a76932020-09-29 16:16:58 -0700949inline void getLastResetTime(const std::shared_ptr<AsyncResp>& aResp)
Gunnar Millsc0557e12020-06-30 11:26:20 -0500950{
951 BMCWEB_LOG_DEBUG << "Getting System Last Reset Time";
952
953 crow::connections::systemBus->async_method_call(
954 [aResp](const boost::system::error_code ec,
955 std::variant<uint64_t>& lastResetTime) {
956 if (ec)
957 {
958 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
959 return;
960 }
961
962 const uint64_t* lastResetTimePtr =
963 std::get_if<uint64_t>(&lastResetTime);
964
965 if (!lastResetTimePtr)
966 {
967 messages::internalError(aResp->res);
968 return;
969 }
970 // LastStateChangeTime is epoch time, in milliseconds
971 // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
972 time_t lastResetTimeStamp =
973 static_cast<time_t>(*lastResetTimePtr / 1000);
974
975 // Convert to ISO 8601 standard
976 aResp->res.jsonValue["LastResetTime"] =
977 crow::utility::getDateTime(lastResetTimeStamp);
978 },
979 "xyz.openbmc_project.State.Chassis",
980 "/xyz/openbmc_project/state/chassis0",
981 "org.freedesktop.DBus.Properties", "Get",
982 "xyz.openbmc_project.State.Chassis", "LastStateChangeTime");
983}
984
985/**
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -0500986 * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
987 *
988 * @param[in] aResp Shared pointer for generating response message.
989 *
990 * @return None.
991 */
Ed Tanousb5a76932020-09-29 16:16:58 -0700992inline void getAutomaticRetry(const std::shared_ptr<AsyncResp>& aResp)
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -0500993{
994 BMCWEB_LOG_DEBUG << "Get Automatic Retry policy";
995
996 crow::connections::systemBus->async_method_call(
997 [aResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500998 std::variant<bool>& autoRebootEnabled) {
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -0500999 if (ec)
1000 {
1001 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
1002 return;
1003 }
1004
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001005 const bool* autoRebootEnabledPtr =
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001006 std::get_if<bool>(&autoRebootEnabled);
1007
1008 if (!autoRebootEnabledPtr)
1009 {
1010 messages::internalError(aResp->res);
1011 return;
1012 }
1013
1014 BMCWEB_LOG_DEBUG << "Auto Reboot: " << *autoRebootEnabledPtr;
1015 if (*autoRebootEnabledPtr == true)
1016 {
1017 aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
1018 "RetryAttempts";
1019 // If AutomaticRetry (AutoReboot) is enabled see how many
1020 // attempts are left
1021 crow::connections::systemBus->async_method_call(
Ed Tanouscb13a392020-07-25 19:02:03 +00001022 [aResp](const boost::system::error_code ec2,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001023 std::variant<uint32_t>& autoRebootAttemptsLeft) {
Ed Tanouscb13a392020-07-25 19:02:03 +00001024 if (ec2)
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001025 {
Ed Tanouscb13a392020-07-25 19:02:03 +00001026 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec2;
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001027 return;
1028 }
1029
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001030 const uint32_t* autoRebootAttemptsLeftPtr =
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001031 std::get_if<uint32_t>(&autoRebootAttemptsLeft);
1032
1033 if (!autoRebootAttemptsLeftPtr)
1034 {
1035 messages::internalError(aResp->res);
1036 return;
1037 }
1038
1039 BMCWEB_LOG_DEBUG << "Auto Reboot Attempts Left: "
1040 << *autoRebootAttemptsLeftPtr;
1041
1042 aResp->res
1043 .jsonValue["Boot"]
1044 ["RemainingAutomaticRetryAttempts"] =
1045 *autoRebootAttemptsLeftPtr;
1046 },
1047 "xyz.openbmc_project.State.Host",
1048 "/xyz/openbmc_project/state/host0",
1049 "org.freedesktop.DBus.Properties", "Get",
1050 "xyz.openbmc_project.Control.Boot.RebootAttempts",
1051 "AttemptsLeft");
1052 }
1053 else
1054 {
1055 aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
1056 "Disabled";
1057 }
1058
1059 // Not on D-Bus. Hardcoded here:
1060 // https://github.com/openbmc/phosphor-state-manager/blob/1dbbef42675e94fb1f78edb87d6b11380260535a/meson_options.txt#L71
1061 aResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] = 3;
Gunnar Mills69f35302020-05-17 16:06:31 -05001062
1063 // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
1064 // and RetryAttempts. OpenBMC only supports Disabled and
1065 // RetryAttempts.
1066 aResp->res.jsonValue["Boot"]["AutomaticRetryConfig@Redfish."
1067 "AllowableValues"] = {"Disabled",
1068 "RetryAttempts"};
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001069 },
1070 "xyz.openbmc_project.Settings",
1071 "/xyz/openbmc_project/control/host0/auto_reboot",
1072 "org.freedesktop.DBus.Properties", "Get",
1073 "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot");
1074}
1075
1076/**
George Liuc6a620f2020-04-10 17:18:11 +08001077 * @brief Retrieves power restore policy over DBUS.
1078 *
1079 * @param[in] aResp Shared pointer for generating response message.
1080 *
1081 * @return None.
1082 */
Ed Tanousb5a76932020-09-29 16:16:58 -07001083inline void getPowerRestorePolicy(const std::shared_ptr<AsyncResp>& aResp)
George Liuc6a620f2020-04-10 17:18:11 +08001084{
1085 BMCWEB_LOG_DEBUG << "Get power restore policy";
1086
1087 crow::connections::systemBus->async_method_call(
1088 [aResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001089 std::variant<std::string>& policy) {
George Liuc6a620f2020-04-10 17:18:11 +08001090 if (ec)
1091 {
1092 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1093 return;
1094 }
1095
1096 const boost::container::flat_map<std::string, std::string>
1097 policyMaps = {
1098 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1099 "AlwaysOn",
1100 "AlwaysOn"},
1101 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1102 "AlwaysOff",
1103 "AlwaysOff"},
1104 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1105 "LastState",
1106 "LastState"}};
1107
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001108 const std::string* policyPtr = std::get_if<std::string>(&policy);
George Liuc6a620f2020-04-10 17:18:11 +08001109
1110 if (!policyPtr)
1111 {
1112 messages::internalError(aResp->res);
1113 return;
1114 }
1115
1116 auto policyMapsIt = policyMaps.find(*policyPtr);
1117 if (policyMapsIt == policyMaps.end())
1118 {
1119 messages::internalError(aResp->res);
1120 return;
1121 }
1122
1123 aResp->res.jsonValue["PowerRestorePolicy"] = policyMapsIt->second;
1124 },
1125 "xyz.openbmc_project.Settings",
1126 "/xyz/openbmc_project/control/host0/power_restore_policy",
1127 "org.freedesktop.DBus.Properties", "Get",
1128 "xyz.openbmc_project.Control.Power.RestorePolicy",
1129 "PowerRestorePolicy");
1130}
1131
1132/**
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301133 * @brief Sets boot properties into DBUS object(s).
1134 *
1135 * @param[in] aResp Shared pointer for generating response message.
1136 * @param[in] oneTimeEnabled Is "one-time" setting already enabled.
1137 * @param[in] bootSource The boot source to set.
1138 * @param[in] bootEnable The source override "enable" to set.
1139 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001140 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301141 */
Ed Tanous23a21a12020-07-25 04:45:05 +00001142inline void setBootModeOrSource(std::shared_ptr<AsyncResp> aResp,
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301143 bool oneTimeEnabled,
1144 std::optional<std::string> bootSource,
1145 std::optional<std::string> bootEnable)
1146{
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001147 std::string bootSourceStr =
1148 "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
1149 std::string bootModeStr =
1150 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301151 bool oneTimeSetting = oneTimeEnabled;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001152 bool useBootSource = true;
1153
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301154 // Validate incoming parameters
1155 if (bootEnable)
1156 {
1157 if (*bootEnable == "Once")
1158 {
1159 oneTimeSetting = true;
1160 }
1161 else if (*bootEnable == "Continuous")
1162 {
1163 oneTimeSetting = false;
1164 }
1165 else if (*bootEnable == "Disabled")
1166 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001167 BMCWEB_LOG_DEBUG << "Boot source override will be disabled";
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301168 oneTimeSetting = false;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001169 useBootSource = false;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301170 }
1171 else
1172 {
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301173 BMCWEB_LOG_DEBUG << "Unsupported value for "
1174 "BootSourceOverrideEnabled: "
1175 << *bootEnable;
1176 messages::propertyValueNotInList(aResp->res, *bootEnable,
1177 "BootSourceOverrideEnabled");
1178 return;
1179 }
1180 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301181
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001182 if (bootSource && useBootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301183 {
1184 // Source target specified
1185 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource;
1186 // Figure out which DBUS interface and property to use
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001187 if (assignBootParameters(aResp, *bootSource, bootSourceStr,
1188 bootModeStr))
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301189 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001190 BMCWEB_LOG_DEBUG
1191 << "Invalid property value for BootSourceOverrideTarget: "
1192 << *bootSource;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301193 messages::propertyValueNotInList(aResp->res, *bootSource,
1194 "BootSourceTargetOverride");
1195 return;
1196 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001197 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301198
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001199 // Act on validated parameters
1200 BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
1201 BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001202 const char* bootObj =
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001203 oneTimeSetting ? "/xyz/openbmc_project/control/host0/boot/one_time"
1204 : "/xyz/openbmc_project/control/host0/boot";
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 source update done.";
1215 },
1216 "xyz.openbmc_project.Settings", bootObj,
1217 "org.freedesktop.DBus.Properties", "Set",
1218 "xyz.openbmc_project.Control.Boot.Source", "BootSource",
1219 std::variant<std::string>(bootSourceStr));
1220
1221 crow::connections::systemBus->async_method_call(
1222 [aResp](const boost::system::error_code ec) {
1223 if (ec)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301224 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001225 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1226 messages::internalError(aResp->res);
1227 return;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301228 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001229 BMCWEB_LOG_DEBUG << "Boot mode update done.";
1230 },
1231 "xyz.openbmc_project.Settings", bootObj,
1232 "org.freedesktop.DBus.Properties", "Set",
1233 "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
1234 std::variant<std::string>(bootModeStr));
1235
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301236 crow::connections::systemBus->async_method_call(
1237 [aResp{std::move(aResp)}](const boost::system::error_code ec) {
1238 if (ec)
1239 {
1240 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1241 messages::internalError(aResp->res);
1242 return;
1243 }
1244 BMCWEB_LOG_DEBUG << "Boot enable update done.";
1245 },
1246 "xyz.openbmc_project.Settings",
1247 "/xyz/openbmc_project/control/host0/boot/one_time",
1248 "org.freedesktop.DBus.Properties", "Set",
1249 "xyz.openbmc_project.Object.Enable", "Enabled",
1250 std::variant<bool>(oneTimeSetting));
1251}
1252
1253/**
1254 * @brief Retrieves "One time" enabled setting over DBUS and calls function to
1255 * set boot source/boot mode properties.
1256 *
1257 * @param[in] aResp Shared pointer for generating response message.
1258 * @param[in] bootSource The boot source from incoming RF request.
1259 * @param[in] bootEnable The boot override enable from incoming RF request.
1260 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001261 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301262 */
Ed Tanousb5a76932020-09-29 16:16:58 -07001263inline void setBootSourceProperties(const std::shared_ptr<AsyncResp>& aResp,
Gunnar Mills69f35302020-05-17 16:06:31 -05001264 std::optional<std::string> bootSource,
1265 std::optional<std::string> bootEnable)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301266{
1267 BMCWEB_LOG_DEBUG << "Set boot information.";
1268
1269 crow::connections::systemBus->async_method_call(
Johnathan Mantey265c1602019-08-08 11:02:51 -07001270 [aResp, bootSource{std::move(bootSource)},
Patrick Williams19bd78d2020-05-13 17:38:24 -05001271 bootEnable{std::move(bootEnable)}](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001272 const std::variant<bool>& oneTime) {
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301273 if (ec)
1274 {
1275 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1276 messages::internalError(aResp->res);
1277 return;
1278 }
1279
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001280 const bool* oneTimePtr = std::get_if<bool>(&oneTime);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301281
1282 if (!oneTimePtr)
1283 {
1284 messages::internalError(aResp->res);
1285 return;
1286 }
1287
1288 BMCWEB_LOG_DEBUG << "Got one time: " << *oneTimePtr;
1289
1290 setBootModeOrSource(aResp, *oneTimePtr, std::move(bootSource),
1291 std::move(bootEnable));
1292 },
1293 "xyz.openbmc_project.Settings",
1294 "/xyz/openbmc_project/control/host0/boot/one_time",
1295 "org.freedesktop.DBus.Properties", "Get",
1296 "xyz.openbmc_project.Object.Enable", "Enabled");
1297}
1298
George Liuc6a620f2020-04-10 17:18:11 +08001299/**
Gunnar Mills69f35302020-05-17 16:06:31 -05001300 * @brief Sets automaticRetry (Auto Reboot)
1301 *
1302 * @param[in] aResp Shared pointer for generating response message.
1303 * @param[in] automaticRetryConfig "AutomaticRetryConfig" from request.
1304 *
1305 * @return None.
1306 */
Ed Tanousb5a76932020-09-29 16:16:58 -07001307inline void setAutomaticRetry(const std::shared_ptr<AsyncResp>& aResp,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001308 const std::string&& automaticRetryConfig)
Gunnar Mills69f35302020-05-17 16:06:31 -05001309{
1310 BMCWEB_LOG_DEBUG << "Set Automatic Retry.";
1311
1312 // OpenBMC only supports "Disabled" and "RetryAttempts".
1313 bool autoRebootEnabled;
1314
1315 if (automaticRetryConfig == "Disabled")
1316 {
1317 autoRebootEnabled = false;
1318 }
1319 else if (automaticRetryConfig == "RetryAttempts")
1320 {
1321 autoRebootEnabled = true;
1322 }
1323 else
1324 {
1325 BMCWEB_LOG_DEBUG << "Invalid property value for "
1326 "AutomaticRetryConfig: "
1327 << automaticRetryConfig;
1328 messages::propertyValueNotInList(aResp->res, automaticRetryConfig,
1329 "AutomaticRetryConfig");
1330 return;
1331 }
1332
1333 crow::connections::systemBus->async_method_call(
1334 [aResp](const boost::system::error_code ec) {
1335 if (ec)
1336 {
1337 messages::internalError(aResp->res);
1338 return;
1339 }
1340 },
1341 "xyz.openbmc_project.Settings",
1342 "/xyz/openbmc_project/control/host0/auto_reboot",
1343 "org.freedesktop.DBus.Properties", "Set",
1344 "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
1345 std::variant<bool>(autoRebootEnabled));
1346}
1347
1348/**
George Liuc6a620f2020-04-10 17:18:11 +08001349 * @brief Sets power restore policy properties.
1350 *
1351 * @param[in] aResp Shared pointer for generating response message.
1352 * @param[in] policy power restore policy properties from request.
1353 *
1354 * @return None.
1355 */
Ed Tanousb5a76932020-09-29 16:16:58 -07001356inline void setPowerRestorePolicy(const std::shared_ptr<AsyncResp>& aResp,
George Liuc6a620f2020-04-10 17:18:11 +08001357 std::optional<std::string> policy)
1358{
1359 BMCWEB_LOG_DEBUG << "Set power restore policy.";
1360
1361 const boost::container::flat_map<std::string, std::string> policyMaps = {
1362 {"AlwaysOn", "xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1363 "AlwaysOn"},
1364 {"AlwaysOff", "xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1365 "AlwaysOff"},
1366 {"LastState", "xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1367 "LastState"}};
1368
1369 std::string powerRestorPolicy;
1370
1371 auto policyMapsIt = policyMaps.find(*policy);
1372 if (policyMapsIt == policyMaps.end())
1373 {
1374 messages::internalError(aResp->res);
1375 return;
1376 }
1377
1378 powerRestorPolicy = policyMapsIt->second;
1379
1380 crow::connections::systemBus->async_method_call(
1381 [aResp](const boost::system::error_code ec) {
1382 if (ec)
1383 {
1384 messages::internalError(aResp->res);
1385 return;
1386 }
1387 },
1388 "xyz.openbmc_project.Settings",
1389 "/xyz/openbmc_project/control/host0/power_restore_policy",
1390 "org.freedesktop.DBus.Properties", "Set",
1391 "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
1392 std::variant<std::string>(powerRestorPolicy));
1393}
1394
AppaRao Pulia6349912019-10-18 17:16:08 +05301395#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1396/**
1397 * @brief Retrieves provisioning status
1398 *
1399 * @param[in] aResp Shared pointer for completing asynchronous calls.
1400 *
1401 * @return None.
1402 */
Ed Tanous23a21a12020-07-25 04:45:05 +00001403inline void getProvisioningStatus(std::shared_ptr<AsyncResp> aResp)
AppaRao Pulia6349912019-10-18 17:16:08 +05301404{
1405 BMCWEB_LOG_DEBUG << "Get OEM information.";
1406 crow::connections::systemBus->async_method_call(
1407 [aResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001408 const std::vector<std::pair<std::string, VariantType>>&
1409 propertiesList) {
AppaRao Pulib99fb1a2020-07-08 16:42:48 +05301410 nlohmann::json& oemPFR =
1411 aResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
James Feist50626f42020-09-23 14:40:47 -07001412 aResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
1413 "#OemComputerSystem.OpenBmc";
1414 oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning";
1415
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 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07001482 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
Yong Li51709ff2019-09-30 14:13:04 +08001483 {
1484 return "ResetSystem";
1485 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07001486 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
Yong Li51709ff2019-09-30 14:13:04 +08001487 {
1488 return "PowerDown";
1489 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07001490 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
Yong Li51709ff2019-09-30 14:13:04 +08001491 {
1492 return "PowerCycle";
1493 }
1494
1495 return "";
1496}
1497
1498/**
Yong Lic45f0082019-10-10 14:19:01 +08001499 *@brief Translates timeout action from Redfish to DBUS property value.
1500 *
1501 *@param[in] rfAction The timeout action in Redfish.
1502 *
1503 *@return Returns as a string, the time_out action as expected by DBUS.
1504 *If translation cannot be done, returns an empty string.
1505 */
1506
Ed Tanous23a21a12020-07-25 04:45:05 +00001507inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
Yong Lic45f0082019-10-10 14:19:01 +08001508{
1509 if (rfAction == "None")
1510 {
1511 return "xyz.openbmc_project.State.Watchdog.Action.None";
1512 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07001513 if (rfAction == "PowerCycle")
Yong Lic45f0082019-10-10 14:19:01 +08001514 {
1515 return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
1516 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07001517 if (rfAction == "PowerDown")
Yong Lic45f0082019-10-10 14:19:01 +08001518 {
1519 return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
1520 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07001521 if (rfAction == "ResetSystem")
Yong Lic45f0082019-10-10 14:19:01 +08001522 {
1523 return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
1524 }
1525
1526 return "";
1527}
1528
1529/**
Yong Li51709ff2019-09-30 14:13:04 +08001530 * @brief Retrieves host watchdog timer properties over DBUS
1531 *
1532 * @param[in] aResp Shared pointer for completing asynchronous calls.
1533 *
1534 * @return None.
1535 */
Ed Tanousb5a76932020-09-29 16:16:58 -07001536inline void getHostWatchdogTimer(const std::shared_ptr<AsyncResp>& aResp)
Yong Li51709ff2019-09-30 14:13:04 +08001537{
1538 BMCWEB_LOG_DEBUG << "Get host watchodg";
1539 crow::connections::systemBus->async_method_call(
1540 [aResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001541 PropertiesType& properties) {
Yong Li51709ff2019-09-30 14:13:04 +08001542 if (ec)
1543 {
1544 // watchdog service is stopped
1545 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1546 return;
1547 }
1548
1549 BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop.";
1550
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001551 nlohmann::json& hostWatchdogTimer =
Yong Li51709ff2019-09-30 14:13:04 +08001552 aResp->res.jsonValue["HostWatchdogTimer"];
1553
1554 // watchdog service is running/enabled
1555 hostWatchdogTimer["Status"]["State"] = "Enabled";
1556
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001557 for (const auto& property : properties)
Yong Li51709ff2019-09-30 14:13:04 +08001558 {
1559 BMCWEB_LOG_DEBUG << "prop=" << property.first;
1560 if (property.first == "Enabled")
1561 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001562 const bool* state = std::get_if<bool>(&property.second);
Yong Li51709ff2019-09-30 14:13:04 +08001563
1564 if (!state)
1565 {
1566 messages::internalError(aResp->res);
1567 continue;
1568 }
1569
1570 hostWatchdogTimer["FunctionEnabled"] = *state;
1571 }
1572 else if (property.first == "ExpireAction")
1573 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001574 const std::string* s =
Yong Li51709ff2019-09-30 14:13:04 +08001575 std::get_if<std::string>(&property.second);
1576 if (!s)
1577 {
1578 messages::internalError(aResp->res);
1579 continue;
1580 }
1581
1582 std::string action = dbusToRfWatchdogAction(*s);
1583 if (action.empty())
1584 {
1585 messages::internalError(aResp->res);
1586 continue;
1587 }
1588 hostWatchdogTimer["TimeoutAction"] = action;
1589 }
1590 }
1591 },
1592 "xyz.openbmc_project.Watchdog", "/xyz/openbmc_project/watchdog/host0",
1593 "org.freedesktop.DBus.Properties", "GetAll",
1594 "xyz.openbmc_project.State.Watchdog");
1595}
1596
1597/**
Yong Lic45f0082019-10-10 14:19:01 +08001598 * @brief Sets Host WatchDog Timer properties.
1599 *
1600 * @param[in] aResp Shared pointer for generating response message.
1601 * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming
1602 * RF request.
1603 * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
1604 *
1605 * @return None.
1606 */
Ed Tanousb5a76932020-09-29 16:16:58 -07001607inline void setWDTProperties(const std::shared_ptr<AsyncResp>& aResp,
Yong Lic45f0082019-10-10 14:19:01 +08001608 const std::optional<bool> wdtEnable,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001609 const std::optional<std::string>& wdtTimeOutAction)
Yong Lic45f0082019-10-10 14:19:01 +08001610{
1611 BMCWEB_LOG_DEBUG << "Set host watchdog";
1612
1613 if (wdtTimeOutAction)
1614 {
1615 std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
1616 // check if TimeOut Action is Valid
1617 if (wdtTimeOutActStr.empty())
1618 {
1619 BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: "
1620 << *wdtTimeOutAction;
1621 messages::propertyValueNotInList(aResp->res, *wdtTimeOutAction,
1622 "TimeoutAction");
1623 return;
1624 }
1625
1626 crow::connections::systemBus->async_method_call(
1627 [aResp](const boost::system::error_code ec) {
1628 if (ec)
1629 {
1630 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1631 messages::internalError(aResp->res);
1632 return;
1633 }
1634 },
1635 "xyz.openbmc_project.Watchdog",
1636 "/xyz/openbmc_project/watchdog/host0",
1637 "org.freedesktop.DBus.Properties", "Set",
1638 "xyz.openbmc_project.State.Watchdog", "ExpireAction",
1639 std::variant<std::string>(wdtTimeOutActStr));
1640 }
1641
1642 if (wdtEnable)
1643 {
1644 crow::connections::systemBus->async_method_call(
1645 [aResp](const boost::system::error_code ec) {
1646 if (ec)
1647 {
1648 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1649 messages::internalError(aResp->res);
1650 return;
1651 }
1652 },
1653 "xyz.openbmc_project.Watchdog",
1654 "/xyz/openbmc_project/watchdog/host0",
1655 "org.freedesktop.DBus.Properties", "Set",
1656 "xyz.openbmc_project.State.Watchdog", "Enabled",
1657 std::variant<bool>(*wdtEnable));
1658 }
1659}
1660
1661/**
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001662 * SystemsCollection derived class for delivering ComputerSystems Collection
1663 * Schema
1664 */
Ed Tanous1abe55e2018-09-05 08:30:59 -07001665class SystemsCollection : public Node
1666{
1667 public:
Ed Tanous52cc1122020-07-18 13:51:21 -07001668 SystemsCollection(App& app) : Node(app, "/redfish/v1/Systems/")
Ed Tanous1abe55e2018-09-05 08:30:59 -07001669 {
Ed Tanous1abe55e2018-09-05 08:30:59 -07001670 entityPrivileges = {
1671 {boost::beast::http::verb::get, {{"Login"}}},
1672 {boost::beast::http::verb::head, {{"Login"}}},
1673 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1674 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1675 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1676 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1677 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001678
Ed Tanous1abe55e2018-09-05 08:30:59 -07001679 private:
Ed Tanouscb13a392020-07-25 19:02:03 +00001680 void doGet(crow::Response& res, const crow::Request&,
1681 const std::vector<std::string>&) override
Ed Tanous1abe55e2018-09-05 08:30:59 -07001682 {
Sunitha Harish462023a2020-02-19 08:34:59 -06001683 std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
Ed Tanous0f74e642018-11-12 15:17:05 -08001684 res.jsonValue["@odata.type"] =
1685 "#ComputerSystemCollection.ComputerSystemCollection";
1686 res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
Ed Tanous0f74e642018-11-12 15:17:05 -08001687 res.jsonValue["Name"] = "Computer System Collection";
Sunitha Harish462023a2020-02-19 08:34:59 -06001688
1689 crow::connections::systemBus->async_method_call(
1690 [asyncResp](const boost::system::error_code ec,
Ed Tanouscb13a392020-07-25 19:02:03 +00001691 const std::variant<std::string>& /*hostName*/) {
Ed Tanous2c70f802020-09-28 14:29:23 -07001692 nlohmann::json& ifaceArray =
Sunitha Harish462023a2020-02-19 08:34:59 -06001693 asyncResp->res.jsonValue["Members"];
Ed Tanous2c70f802020-09-28 14:29:23 -07001694 ifaceArray = nlohmann::json::array();
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001695 auto& count = asyncResp->res.jsonValue["Members@odata.count"];
Sunitha Harish462023a2020-02-19 08:34:59 -06001696 count = 0;
Ed Tanous2c70f802020-09-28 14:29:23 -07001697 ifaceArray.push_back(
Ed Tanouscb13a392020-07-25 19:02:03 +00001698 {{"@odata.id", "/redfish/v1/Systems/system"}});
1699 if (!ec)
Sunitha Harish462023a2020-02-19 08:34:59 -06001700 {
Ed Tanouscb13a392020-07-25 19:02:03 +00001701 BMCWEB_LOG_DEBUG << "Hypervisor is available";
Ed Tanous2c70f802020-09-28 14:29:23 -07001702 ifaceArray.push_back(
Ed Tanouscb13a392020-07-25 19:02:03 +00001703 {{"@odata.id", "/redfish/v1/Systems/hypervisor"}});
Ed Tanous2c70f802020-09-28 14:29:23 -07001704 count = ifaceArray.size();
Sunitha Harish462023a2020-02-19 08:34:59 -06001705 return;
1706 }
Sunitha Harish462023a2020-02-19 08:34:59 -06001707 },
Sunitha Harish8e651fb2020-06-17 06:06:25 -05001708 "xyz.openbmc_project.Settings",
1709 "/xyz/openbmc_project/network/hypervisor",
Sunitha Harish462023a2020-02-19 08:34:59 -06001710 "org.freedesktop.DBus.Properties", "Get",
1711 "xyz.openbmc_project.Network.SystemConfiguration", "HostName");
Ed Tanous1abe55e2018-09-05 08:30:59 -07001712 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001713};
1714
1715/**
Ed Tanouscc340dd2018-08-29 13:43:38 -07001716 * SystemActionsReset class supports handle POST method for Reset action.
1717 * The class retrieves and sends data directly to D-Bus.
1718 */
1719class SystemActionsReset : public Node
1720{
1721 public:
Ed Tanous52cc1122020-07-18 13:51:21 -07001722 SystemActionsReset(App& app) :
Ed Tanous029573d2019-02-01 10:57:49 -08001723 Node(app, "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/")
Ed Tanouscc340dd2018-08-29 13:43:38 -07001724 {
1725 entityPrivileges = {
1726 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1727 }
1728
1729 private:
1730 /**
1731 * Function handles POST method request.
1732 * Analyzes POST body message before sends Reset request data to D-Bus.
1733 */
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001734 void doPost(crow::Response& res, const crow::Request& req,
Ed Tanouscb13a392020-07-25 19:02:03 +00001735 const std::vector<std::string>&) override
Ed Tanouscc340dd2018-08-29 13:43:38 -07001736 {
Ed Tanous9712f8a2018-09-21 13:38:49 -07001737 auto asyncResp = std::make_shared<AsyncResp>(res);
1738
1739 std::string resetType;
1740 if (!json_util::readJson(req, res, "ResetType", resetType))
Ed Tanouscc340dd2018-08-29 13:43:38 -07001741 {
1742 return;
1743 }
1744
Jason M. Billsd22c8392019-06-03 13:59:03 -07001745 // Get the command and host vs. chassis
Ed Tanous9712f8a2018-09-21 13:38:49 -07001746 std::string command;
Jason M. Billsd22c8392019-06-03 13:59:03 -07001747 bool hostCommand;
Ed Tanousd4d25792020-09-29 15:15:03 -07001748 if ((resetType == "On") || (resetType == "ForceOn"))
Ed Tanous9712f8a2018-09-21 13:38:49 -07001749 {
1750 command = "xyz.openbmc_project.State.Host.Transition.On";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001751 hostCommand = true;
1752 }
1753 else if (resetType == "ForceOff")
1754 {
1755 command = "xyz.openbmc_project.State.Chassis.Transition.Off";
1756 hostCommand = false;
1757 }
Jason M. Billsd22c8392019-06-03 13:59:03 -07001758 else if (resetType == "ForceRestart")
1759 {
Jason M. Bills86a08512020-02-04 13:15:49 -08001760 command =
1761 "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
1762 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001763 }
1764 else if (resetType == "GracefulShutdown")
1765 {
1766 command = "xyz.openbmc_project.State.Host.Transition.Off";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001767 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001768 }
1769 else if (resetType == "GracefulRestart")
1770 {
Jason M. Bills86a08512020-02-04 13:15:49 -08001771 command =
1772 "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001773 hostCommand = true;
1774 }
1775 else if (resetType == "PowerCycle")
1776 {
Jason M. Bills86a08512020-02-04 13:15:49 -08001777 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
1778 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001779 }
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001780 else if (resetType == "Nmi")
1781 {
1782 doNMI(asyncResp);
1783 return;
1784 }
Ed Tanous9712f8a2018-09-21 13:38:49 -07001785 else
1786 {
Jason M. Billsf12894f2018-10-09 12:45:45 -07001787 messages::actionParameterUnknown(res, "Reset", resetType);
Ed Tanous9712f8a2018-09-21 13:38:49 -07001788 return;
1789 }
1790
Jason M. Billsd22c8392019-06-03 13:59:03 -07001791 if (hostCommand)
1792 {
1793 crow::connections::systemBus->async_method_call(
1794 [asyncResp, resetType](const boost::system::error_code ec) {
1795 if (ec)
1796 {
1797 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1798 if (ec.value() == boost::asio::error::invalid_argument)
1799 {
1800 messages::actionParameterNotSupported(
1801 asyncResp->res, resetType, "Reset");
1802 }
1803 else
1804 {
1805 messages::internalError(asyncResp->res);
1806 }
1807 return;
1808 }
1809 messages::success(asyncResp->res);
1810 },
1811 "xyz.openbmc_project.State.Host",
1812 "/xyz/openbmc_project/state/host0",
1813 "org.freedesktop.DBus.Properties", "Set",
1814 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
1815 std::variant<std::string>{command});
1816 }
1817 else
1818 {
1819 crow::connections::systemBus->async_method_call(
1820 [asyncResp, resetType](const boost::system::error_code ec) {
1821 if (ec)
1822 {
1823 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1824 if (ec.value() == boost::asio::error::invalid_argument)
1825 {
1826 messages::actionParameterNotSupported(
1827 asyncResp->res, resetType, "Reset");
1828 }
1829 else
1830 {
1831 messages::internalError(asyncResp->res);
1832 }
1833 return;
1834 }
1835 messages::success(asyncResp->res);
1836 },
1837 "xyz.openbmc_project.State.Chassis",
1838 "/xyz/openbmc_project/state/chassis0",
1839 "org.freedesktop.DBus.Properties", "Set",
1840 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
1841 std::variant<std::string>{command});
1842 }
Ed Tanouscc340dd2018-08-29 13:43:38 -07001843 }
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001844 /**
1845 * Function transceives data with dbus directly.
1846 */
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001847 void doNMI(const std::shared_ptr<AsyncResp>& asyncResp)
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001848 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001849 constexpr char const* serviceName =
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001850 "xyz.openbmc_project.Control.Host.NMI";
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001851 constexpr char const* objectPath =
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001852 "/xyz/openbmc_project/control/host0/nmi";
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001853 constexpr char const* interfaceName =
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001854 "xyz.openbmc_project.Control.Host.NMI";
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001855 constexpr char const* method = "NMI";
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001856
1857 crow::connections::systemBus->async_method_call(
1858 [asyncResp](const boost::system::error_code ec) {
1859 if (ec)
1860 {
1861 BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
1862 messages::internalError(asyncResp->res);
1863 return;
1864 }
1865 messages::success(asyncResp->res);
1866 },
1867 serviceName, objectPath, interfaceName, method);
1868 }
Ed Tanouscc340dd2018-08-29 13:43:38 -07001869};
1870
1871/**
Ed Tanous66173382018-08-15 18:20:59 -07001872 * Systems derived class for delivering Computer Systems Schema.
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001873 */
Ed Tanous1abe55e2018-09-05 08:30:59 -07001874class Systems : public Node
1875{
1876 public:
1877 /*
1878 * Default Constructor
1879 */
Ed Tanous52cc1122020-07-18 13:51:21 -07001880 Systems(App& app) : Node(app, "/redfish/v1/Systems/system/")
Ed Tanous1abe55e2018-09-05 08:30:59 -07001881 {
Ed Tanous1abe55e2018-09-05 08:30:59 -07001882 entityPrivileges = {
1883 {boost::beast::http::verb::get, {{"Login"}}},
1884 {boost::beast::http::verb::head, {{"Login"}}},
1885 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1886 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1887 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1888 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001889 }
1890
Ed Tanous1abe55e2018-09-05 08:30:59 -07001891 private:
Ed Tanous1abe55e2018-09-05 08:30:59 -07001892 /**
1893 * Functions triggers appropriate requests on DBus
1894 */
Ed Tanouscb13a392020-07-25 19:02:03 +00001895 void doGet(crow::Response& res, const crow::Request&,
1896 const std::vector<std::string>&) override
Ed Tanous1abe55e2018-09-05 08:30:59 -07001897 {
Gunnar Millsc0557e12020-06-30 11:26:20 -05001898 res.jsonValue["@odata.type"] = "#ComputerSystem.v1_12_0.ComputerSystem";
Gunnar Mills450a25c2020-04-14 21:34:07 -05001899 res.jsonValue["Name"] = "system";
Ed Tanous029573d2019-02-01 10:57:49 -08001900 res.jsonValue["Id"] = "system";
Ed Tanous0f74e642018-11-12 15:17:05 -08001901 res.jsonValue["SystemType"] = "Physical";
1902 res.jsonValue["Description"] = "Computer System";
Ed Tanous0f74e642018-11-12 15:17:05 -08001903 res.jsonValue["ProcessorSummary"]["Count"] = 0;
1904 res.jsonValue["ProcessorSummary"]["Status"]["State"] = "Disabled";
Cheng C Yang5fd7ba62019-11-28 15:58:08 +08001905 res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = uint64_t(0);
Ed Tanous0f74e642018-11-12 15:17:05 -08001906 res.jsonValue["MemorySummary"]["Status"]["State"] = "Disabled";
Ed Tanous029573d2019-02-01 10:57:49 -08001907 res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
Ed Tanous04a258f2018-10-15 08:00:41 -07001908
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001909 res.jsonValue["Processors"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001910 {"@odata.id", "/redfish/v1/Systems/system/Processors"}};
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001911 res.jsonValue["Memory"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001912 {"@odata.id", "/redfish/v1/Systems/system/Memory"}};
Nikhil Potadea25aecc2019-08-23 16:35:26 -07001913 res.jsonValue["Storage"] = {
1914 {"@odata.id", "/redfish/v1/Systems/system/Storage"}};
Ed Tanous029573d2019-02-01 10:57:49 -08001915
Ed Tanouscc340dd2018-08-29 13:43:38 -07001916 res.jsonValue["Actions"]["#ComputerSystem.Reset"] = {
1917 {"target",
Ed Tanous029573d2019-02-01 10:57:49 -08001918 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"},
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05301919 {"@Redfish.ActionInfo",
1920 "/redfish/v1/Systems/system/ResetActionInfo"}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001921
Jason M. Billsc4bf6372018-11-05 13:48:27 -08001922 res.jsonValue["LogServices"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001923 {"@odata.id", "/redfish/v1/Systems/system/LogServices"}};
Jason M. Billsc4bf6372018-11-05 13:48:27 -08001924
Carol Wangd82a3ac2019-11-21 13:56:38 +08001925 res.jsonValue["Bios"] = {
1926 {"@odata.id", "/redfish/v1/Systems/system/Bios"}};
1927
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001928 res.jsonValue["Links"]["ManagedBy"] = {
1929 {{"@odata.id", "/redfish/v1/Managers/bmc"}}};
1930
1931 res.jsonValue["Status"] = {
1932 {"Health", "OK"},
1933 {"State", "Enabled"},
1934 };
Ed Tanousa0803ef2018-08-29 13:29:23 -07001935 auto asyncResp = std::make_shared<AsyncResp>(res);
Ed Tanous1abe55e2018-09-05 08:30:59 -07001936
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001937 constexpr const std::array<const char*, 4> inventoryForSystems = {
James Feistb49ac872019-05-21 15:12:01 -07001938 "xyz.openbmc_project.Inventory.Item.Dimm",
James Feist2ad9c2f2019-10-29 16:26:48 -07001939 "xyz.openbmc_project.Inventory.Item.Cpu",
James Feiste284a7c2019-11-20 16:20:23 -08001940 "xyz.openbmc_project.Inventory.Item.Drive",
1941 "xyz.openbmc_project.Inventory.Item.StorageController"};
James Feistb49ac872019-05-21 15:12:01 -07001942
1943 auto health = std::make_shared<HealthPopulate>(asyncResp);
1944 crow::connections::systemBus->async_method_call(
1945 [health](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001946 std::vector<std::string>& resp) {
James Feistb49ac872019-05-21 15:12:01 -07001947 if (ec)
1948 {
1949 // no inventory
1950 return;
1951 }
1952
1953 health->inventory = std::move(resp);
1954 },
1955 "xyz.openbmc_project.ObjectMapper",
1956 "/xyz/openbmc_project/object_mapper",
1957 "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", "/",
1958 int32_t(0), inventoryForSystems);
1959
1960 health->populate();
1961
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001962 getMainChassisId(asyncResp, [](const std::string& chassisId,
Ed Tanousb5a76932020-09-29 16:16:58 -07001963 const std::shared_ptr<AsyncResp>& aRsp) {
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001964 aRsp->res.jsonValue["Links"]["Chassis"] = {
1965 {{"@odata.id", "/redfish/v1/Chassis/" + chassisId}}};
1966 });
AppaRao Pulia3002222019-11-12 21:32:59 +05301967
1968 getIndicatorLedState(asyncResp);
James Feist5bc2dc82019-10-22 14:33:16 -07001969 getComputerSystem(asyncResp, health);
Ed Tanous6c34de42018-08-29 13:37:36 -07001970 getHostState(asyncResp);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301971 getBootProperties(asyncResp);
Jason M. Billsadbe1922019-10-14 15:44:35 -07001972 getPCIeDeviceList(asyncResp, "PCIeDevices");
Yong Li51709ff2019-09-30 14:13:04 +08001973 getHostWatchdogTimer(asyncResp);
George Liuc6a620f2020-04-10 17:18:11 +08001974 getPowerRestorePolicy(asyncResp);
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001975 getAutomaticRetry(asyncResp);
Gunnar Millsc0557e12020-06-30 11:26:20 -05001976 getLastResetTime(asyncResp);
AppaRao Pulia6349912019-10-18 17:16:08 +05301977#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1978 getProvisioningStatus(asyncResp);
1979#endif
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001980 }
1981
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001982 void doPatch(crow::Response& res, const crow::Request& req,
Ed Tanouscb13a392020-07-25 19:02:03 +00001983 const std::vector<std::string>&) override
Ed Tanous1abe55e2018-09-05 08:30:59 -07001984 {
Santosh Puranikcde19e52019-02-20 00:10:56 +05301985 std::optional<std::string> indicatorLed;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301986 std::optional<nlohmann::json> bootProps;
Yong Lic45f0082019-10-10 14:19:01 +08001987 std::optional<nlohmann::json> wdtTimerProps;
George Liuc6a620f2020-04-10 17:18:11 +08001988 std::optional<std::string> powerRestorePolicy;
Santosh Puranik41352c22019-07-03 05:35:49 -05001989 auto asyncResp = std::make_shared<AsyncResp>(res);
1990
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001991 if (!json_util::readJson(req, res, "IndicatorLED", indicatorLed, "Boot",
George Liuc6a620f2020-04-10 17:18:11 +08001992 bootProps, "WatchdogTimer", wdtTimerProps,
1993 "PowerRestorePolicy", powerRestorePolicy))
Ed Tanous66173382018-08-15 18:20:59 -07001994 {
Ed Tanous9712f8a2018-09-21 13:38:49 -07001995 return;
1996 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301997
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001998 res.result(boost::beast::http::status::no_content);
Yong Lic45f0082019-10-10 14:19:01 +08001999
2000 if (wdtTimerProps)
2001 {
2002 std::optional<bool> wdtEnable;
2003 std::optional<std::string> wdtTimeOutAction;
2004
2005 if (!json_util::readJson(*wdtTimerProps, asyncResp->res,
2006 "FunctionEnabled", wdtEnable,
2007 "TimeoutAction", wdtTimeOutAction))
2008 {
2009 return;
2010 }
2011 setWDTProperties(asyncResp, std::move(wdtEnable),
2012 std::move(wdtTimeOutAction));
2013 }
2014
Santosh Puranik491d8ee2019-02-06 19:46:56 +05302015 if (bootProps)
2016 {
2017 std::optional<std::string> bootSource;
2018 std::optional<std::string> bootEnable;
Gunnar Mills69f35302020-05-17 16:06:31 -05002019 std::optional<std::string> automaticRetryConfig;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05302020
Gunnar Mills69f35302020-05-17 16:06:31 -05002021 if (!json_util::readJson(
2022 *bootProps, asyncResp->res, "BootSourceOverrideTarget",
2023 bootSource, "BootSourceOverrideEnabled", bootEnable,
2024 "AutomaticRetryConfig", automaticRetryConfig))
Santosh Puranik491d8ee2019-02-06 19:46:56 +05302025 {
2026 return;
2027 }
Gunnar Mills69f35302020-05-17 16:06:31 -05002028 if (bootSource || bootEnable)
2029 {
2030 setBootSourceProperties(asyncResp, std::move(bootSource),
2031 std::move(bootEnable));
2032 }
2033 if (automaticRetryConfig)
2034 {
2035 setAutomaticRetry(asyncResp, std::move(*automaticRetryConfig));
2036 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05302037 }
Johnathan Mantey265c1602019-08-08 11:02:51 -07002038
Ed Tanous9712f8a2018-09-21 13:38:49 -07002039 if (indicatorLed)
2040 {
AppaRao Pulia3002222019-11-12 21:32:59 +05302041 setIndicatorLedState(asyncResp, std::move(*indicatorLed));
Ed Tanous1abe55e2018-09-05 08:30:59 -07002042 }
George Liuc6a620f2020-04-10 17:18:11 +08002043
2044 if (powerRestorePolicy)
2045 {
2046 setPowerRestorePolicy(asyncResp, std::move(*powerRestorePolicy));
2047 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002048 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002049};
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05302050
2051/**
2052 * SystemResetActionInfo derived class for delivering Computer Systems
2053 * ResetType AllowableValues using ResetInfo schema.
2054 */
2055class SystemResetActionInfo : public Node
2056{
2057 public:
2058 /*
2059 * Default Constructor
2060 */
Ed Tanous52cc1122020-07-18 13:51:21 -07002061 SystemResetActionInfo(App& app) :
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05302062 Node(app, "/redfish/v1/Systems/system/ResetActionInfo/")
2063 {
2064 entityPrivileges = {
2065 {boost::beast::http::verb::get, {{"Login"}}},
2066 {boost::beast::http::verb::head, {{"Login"}}},
2067 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
2068 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
2069 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
2070 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
2071 }
2072
2073 private:
2074 /**
2075 * Functions triggers appropriate requests on DBus
2076 */
Ed Tanouscb13a392020-07-25 19:02:03 +00002077 void doGet(crow::Response& res, const crow::Request&,
2078 const std::vector<std::string>&) override
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05302079 {
2080 res.jsonValue = {
2081 {"@odata.type", "#ActionInfo.v1_1_2.ActionInfo"},
2082 {"@odata.id", "/redfish/v1/Systems/system/ResetActionInfo"},
2083 {"Name", "Reset Action Info"},
2084 {"Id", "ResetActionInfo"},
2085 {"Parameters",
2086 {{{"Name", "ResetType"},
2087 {"Required", true},
2088 {"DataType", "String"},
2089 {"AllowableValues",
2090 {"On", "ForceOff", "ForceOn", "ForceRestart", "GracefulRestart",
2091 "GracefulShutdown", "PowerCycle", "Nmi"}}}}}};
2092 res.end();
2093 }
2094};
Ed Tanous1abe55e2018-09-05 08:30:59 -07002095} // namespace redfish