blob: f97dba29b64a35af2a0b754dde12212fc9a6d406 [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 */
zhanghch058d1b46d2021-04-01 11:18:24 +080041inline void
42 updateDimmProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
43 const std::variant<bool>& dimmState)
Alpana Kumari9d3ae102019-04-12 06:49:32 -050044{
Gunnar Mills1214b7e2020-06-04 10:11:30 -050045 const bool* isDimmFunctional = std::get_if<bool>(&dimmState);
Alpana Kumari9d3ae102019-04-12 06:49:32 -050046 if (isDimmFunctional == nullptr)
47 {
48 messages::internalError(aResp->res);
49 return;
50 }
Gunnar Mills698654b2019-10-16 13:17:37 -050051 BMCWEB_LOG_DEBUG << "Dimm Functional: " << *isDimmFunctional;
Alpana Kumari9d3ae102019-04-12 06:49:32 -050052
Gunnar Mills4e0453b2020-07-08 14:00:30 -050053 // Set it as Enabled if at least one DIMM is functional
Alpana Kumari9d3ae102019-04-12 06:49:32 -050054 // Update STATE only if previous State was DISABLED and current Dimm is
55 // ENABLED.
Gunnar Mills1214b7e2020-06-04 10:11:30 -050056 nlohmann::json& prevMemSummary =
Alpana Kumari9d3ae102019-04-12 06:49:32 -050057 aResp->res.jsonValue["MemorySummary"]["Status"]["State"];
58 if (prevMemSummary == "Disabled")
59 {
60 if (*isDimmFunctional == true)
61 {
62 aResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
63 "Enabled";
64 }
65 }
66}
67
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050068/*
69 * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState
70 *
71 * @param[in] aResp Shared pointer for completing asynchronous calls
72 * @param[in] cpuPresenceState CPU present or not
73 *
74 * @return None.
75 */
zhanghch058d1b46d2021-04-01 11:18:24 +080076inline void
77 modifyCpuPresenceState(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
78 const std::variant<bool>& cpuPresenceState)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050079{
Gunnar Mills1214b7e2020-06-04 10:11:30 -050080 const bool* isCpuPresent = std::get_if<bool>(&cpuPresenceState);
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050081
82 if (isCpuPresent == nullptr)
83 {
84 messages::internalError(aResp->res);
85 return;
86 }
Gunnar Mills698654b2019-10-16 13:17:37 -050087 BMCWEB_LOG_DEBUG << "Cpu Present: " << *isCpuPresent;
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050088
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050089 if (*isCpuPresent == true)
90 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -050091 nlohmann::json& procCount =
James Feistb4b95952019-12-05 15:01:55 -080092 aResp->res.jsonValue["ProcessorSummary"]["Count"];
93 auto procCountPtr =
Gunnar Mills1214b7e2020-06-04 10:11:30 -050094 procCount.get_ptr<nlohmann::json::number_integer_t*>();
James Feistb4b95952019-12-05 15:01:55 -080095 if (procCountPtr != nullptr)
96 {
97 // shouldn't be possible to be nullptr
98 *procCountPtr += 1;
99 }
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500100 }
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500101}
102
103/*
104 * @brief Update "ProcessorSummary" "Status" "State" based on
105 * CPU Functional State
106 *
107 * @param[in] aResp Shared pointer for completing asynchronous calls
108 * @param[in] cpuFunctionalState is CPU functional true/false
109 *
110 * @return None.
111 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000112inline void
zhanghch058d1b46d2021-04-01 11:18:24 +0800113 modifyCpuFunctionalState(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Ed Tanous23a21a12020-07-25 04:45:05 +0000114 const std::variant<bool>& cpuFunctionalState)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500115{
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500116 const bool* isCpuFunctional = std::get_if<bool>(&cpuFunctionalState);
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500117
118 if (isCpuFunctional == nullptr)
119 {
120 messages::internalError(aResp->res);
121 return;
122 }
Gunnar Mills698654b2019-10-16 13:17:37 -0500123 BMCWEB_LOG_DEBUG << "Cpu Functional: " << *isCpuFunctional;
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500124
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500125 nlohmann::json& prevProcState =
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500126 aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"];
127
Gunnar Mills4e0453b2020-07-08 14:00:30 -0500128 // Set it as Enabled if at least one CPU is functional
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500129 // Update STATE only if previous State was Non_Functional and current CPU is
130 // Functional.
131 if (prevProcState == "Disabled")
132 {
133 if (*isCpuFunctional == true)
134 {
135 aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
136 "Enabled";
137 }
138 }
139}
140
141/*
Ed Tanous6c34de42018-08-29 13:37:36 -0700142 * @brief Retrieves computer system properties over dbus
143 *
144 * @param[in] aResp Shared pointer for completing asynchronous calls
Gunnar Mills8f9ee3c2020-10-30 16:15:13 -0500145 * @param[in] systemHealth Shared HealthPopulate pointer
Ed Tanous6c34de42018-08-29 13:37:36 -0700146 *
147 * @return None.
148 */
Ed Tanousb5a76932020-09-29 16:16:58 -0700149inline void
zhanghch058d1b46d2021-04-01 11:18:24 +0800150 getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Ed Tanousb5a76932020-09-29 16:16:58 -0700151 const std::shared_ptr<HealthPopulate>& systemHealth)
Ed Tanous6c34de42018-08-29 13:37:36 -0700152{
Ed Tanous6c34de42018-08-29 13:37:36 -0700153 BMCWEB_LOG_DEBUG << "Get available system components.";
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500154
Ed Tanous6c34de42018-08-29 13:37:36 -0700155 crow::connections::systemBus->async_method_call(
James Feist5bc2dc82019-10-22 14:33:16 -0700156 [aResp, systemHealth](
Ed Tanous6c34de42018-08-29 13:37:36 -0700157 const boost::system::error_code ec,
158 const std::vector<std::pair<
159 std::string,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500160 std::vector<std::pair<std::string, std::vector<std::string>>>>>&
161 subtree) {
Ed Tanous6c34de42018-08-29 13:37:36 -0700162 if (ec)
163 {
164 BMCWEB_LOG_DEBUG << "DBUS response error";
Jason M. Billsf12894f2018-10-09 12:45:45 -0700165 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700166 return;
167 }
Ed Tanous6c34de42018-08-29 13:37:36 -0700168 // Iterate over all retrieved ObjectPaths.
169 for (const std::pair<std::string,
170 std::vector<std::pair<
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500171 std::string, std::vector<std::string>>>>&
172 object : subtree)
Ed Tanous6c34de42018-08-29 13:37:36 -0700173 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500174 const std::string& path = object.first;
Ed Tanous6c34de42018-08-29 13:37:36 -0700175 BMCWEB_LOG_DEBUG << "Got path: " << path;
176 const std::vector<
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500177 std::pair<std::string, std::vector<std::string>>>&
178 connectionNames = object.second;
Ed Tanous6c34de42018-08-29 13:37:36 -0700179 if (connectionNames.size() < 1)
180 {
181 continue;
182 }
Ed Tanous029573d2019-02-01 10:57:49 -0800183
James Feist5bc2dc82019-10-22 14:33:16 -0700184 auto memoryHealth = std::make_shared<HealthPopulate>(
185 aResp, aResp->res.jsonValue["MemorySummary"]["Status"]);
186
187 auto cpuHealth = std::make_shared<HealthPopulate>(
188 aResp, aResp->res.jsonValue["ProcessorSummary"]["Status"]);
189
190 systemHealth->children.emplace_back(memoryHealth);
191 systemHealth->children.emplace_back(cpuHealth);
192
Ed Tanous029573d2019-02-01 10:57:49 -0800193 // This is not system, so check if it's cpu, dimm, UUID or
194 // BiosVer
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500195 for (const auto& connection : connectionNames)
Ed Tanous6c34de42018-08-29 13:37:36 -0700196 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500197 for (const auto& interfaceName : connection.second)
Ed Tanous6c34de42018-08-29 13:37:36 -0700198 {
Ed Tanous029573d2019-02-01 10:57:49 -0800199 if (interfaceName ==
200 "xyz.openbmc_project.Inventory.Item.Dimm")
Ed Tanous6c34de42018-08-29 13:37:36 -0700201 {
Ed Tanous029573d2019-02-01 10:57:49 -0800202 BMCWEB_LOG_DEBUG
203 << "Found Dimm, now get its properties.";
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500204
Ed Tanous029573d2019-02-01 10:57:49 -0800205 crow::connections::systemBus->async_method_call(
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500206 [aResp, service{connection.first},
Ed Tanousf23b7292020-10-15 09:41:17 -0700207 path](const boost::system::error_code ec2,
208 const std::vector<
209 std::pair<std::string, VariantType>>&
210 properties) {
Ed Tanouscb13a392020-07-25 19:02:03 +0000211 if (ec2)
Ed Tanous029573d2019-02-01 10:57:49 -0800212 {
213 BMCWEB_LOG_ERROR
Ed Tanouscb13a392020-07-25 19:02:03 +0000214 << "DBUS response error " << ec2;
Ed Tanous029573d2019-02-01 10:57:49 -0800215 messages::internalError(aResp->res);
216 return;
217 }
218 BMCWEB_LOG_DEBUG << "Got "
219 << properties.size()
Gunnar Mills698654b2019-10-16 13:17:37 -0500220 << " Dimm properties.";
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500221
222 if (properties.size() > 0)
Ed Tanous029573d2019-02-01 10:57:49 -0800223 {
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500224 for (const std::pair<std::string,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500225 VariantType>&
226 property : properties)
Ed Tanous6c34de42018-08-29 13:37:36 -0700227 {
Cheng C Yang5fd7ba62019-11-28 15:58:08 +0800228 if (property.first !=
229 "MemorySizeInKB")
Ed Tanous6c34de42018-08-29 13:37:36 -0700230 {
Cheng C Yang5fd7ba62019-11-28 15:58:08 +0800231 continue;
Ed Tanous6c34de42018-08-29 13:37:36 -0700232 }
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500233 const uint32_t* value =
Patrick Williams8d78b7a2020-05-13 11:24:20 -0500234 std::get_if<uint32_t>(
235 &property.second);
Cheng C Yang5fd7ba62019-11-28 15:58:08 +0800236 if (value == nullptr)
237 {
238 BMCWEB_LOG_DEBUG
239 << "Find incorrect type of "
240 "MemorySize";
241 continue;
242 }
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500243 nlohmann::json& totalMemory =
Cheng C Yang5fd7ba62019-11-28 15:58:08 +0800244 aResp->res
245 .jsonValue["MemorySummar"
246 "y"]
247 ["TotalSystemMe"
248 "moryGiB"];
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500249 uint64_t* preValue =
Cheng C Yang5fd7ba62019-11-28 15:58:08 +0800250 totalMemory
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500251 .get_ptr<uint64_t*>();
Cheng C Yang5fd7ba62019-11-28 15:58:08 +0800252 if (preValue == nullptr)
253 {
254 continue;
255 }
256 aResp->res
257 .jsonValue["MemorySummary"]
258 ["TotalSystemMemoryGi"
259 "B"] =
260 *value / (1024 * 1024) +
261 *preValue;
262 aResp->res
263 .jsonValue["MemorySummary"]
264 ["Status"]["State"] =
265 "Enabled";
Ed Tanous6c34de42018-08-29 13:37:36 -0700266 }
Ed Tanous029573d2019-02-01 10:57:49 -0800267 }
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500268 else
269 {
270 auto getDimmProperties =
271 [aResp](
272 const boost::system::error_code
Ed Tanouscb13a392020-07-25 19:02:03 +0000273 ec3,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500274 const std::variant<bool>&
275 dimmState) {
Ed Tanouscb13a392020-07-25 19:02:03 +0000276 if (ec3)
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500277 {
278 BMCWEB_LOG_ERROR
279 << "DBUS response "
280 "error "
Ed Tanouscb13a392020-07-25 19:02:03 +0000281 << ec3;
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500282 return;
283 }
284 updateDimmProperties(aResp,
285 dimmState);
286 };
287 crow::connections::systemBus
288 ->async_method_call(
289 std::move(getDimmProperties),
290 service, path,
291 "org.freedesktop.DBus."
292 "Properties",
293 "Get",
294 "xyz.openbmc_project.State."
295 "Decorator.OperationalStatus",
296 "Functional");
297 }
Ed Tanous029573d2019-02-01 10:57:49 -0800298 },
299 connection.first, path,
300 "org.freedesktop.DBus.Properties", "GetAll",
301 "xyz.openbmc_project.Inventory.Item.Dimm");
James Feist5bc2dc82019-10-22 14:33:16 -0700302
303 memoryHealth->inventory.emplace_back(path);
Ed Tanous029573d2019-02-01 10:57:49 -0800304 }
305 else if (interfaceName ==
306 "xyz.openbmc_project.Inventory.Item.Cpu")
307 {
308 BMCWEB_LOG_DEBUG
309 << "Found Cpu, now get its properties.";
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500310
Ed Tanous029573d2019-02-01 10:57:49 -0800311 crow::connections::systemBus->async_method_call(
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500312 [aResp, service{connection.first},
Ed Tanousf23b7292020-10-15 09:41:17 -0700313 path](const boost::system::error_code ec2,
314 const std::vector<
315 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") ||
SunnySrivastava19845235d962020-06-30 03:09:00 -0500544 (propertyName == "Model") ||
545 (propertyName == "SubModel"))
Ed Tanous029573d2019-02-01 10:57:49 -0800546 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500547 const std::string* value =
beccabroekfc5afcf2019-03-05 14:35:15 -0600548 std::get_if<std::string>(
549 &property.second);
550 if (value != nullptr)
551 {
552 aResp->res
553 .jsonValue[propertyName] =
554 *value;
555 }
Ed Tanous029573d2019-02-01 10:57:49 -0800556 }
557 }
Gunnar Millsc1e236a2020-04-14 21:36:33 -0500558
Andrew Geisslercb7e1e72019-02-19 13:05:38 -0600559 // Grab the bios version
Gunnar Millsf97ddba2020-08-20 15:57:40 -0500560 fw_util::populateFirmwareInformation(
Andrew Geisslercb7e1e72019-02-19 13:05:38 -0600561 aResp, fw_util::biosPurpose,
Gunnar Mills72d566d2020-07-21 12:44:00 -0500562 "BiosVersion", false);
Ed Tanous029573d2019-02-01 10:57:49 -0800563 },
564 connection.first, path,
565 "org.freedesktop.DBus.Properties", "GetAll",
566 "xyz.openbmc_project.Inventory.Decorator."
567 "Asset");
James Feiste4a4b9a2019-06-20 14:08:07 -0700568
569 crow::connections::systemBus->async_method_call(
570 [aResp](
Ed Tanouscb13a392020-07-25 19:02:03 +0000571 const boost::system::error_code ec2,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500572 const std::variant<std::string>& property) {
Ed Tanouscb13a392020-07-25 19:02:03 +0000573 if (ec2)
James Feiste4a4b9a2019-06-20 14:08:07 -0700574 {
575 // doesn't have to include this
576 // interface
577 return;
578 }
579
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500580 const std::string* value =
James Feiste4a4b9a2019-06-20 14:08:07 -0700581 std::get_if<std::string>(&property);
582 if (value != nullptr)
583 {
584 aResp->res.jsonValue["AssetTag"] =
585 *value;
586 }
587 },
588 connection.first, path,
589 "org.freedesktop.DBus.Properties", "Get",
590 "xyz.openbmc_project.Inventory.Decorator."
591 "AssetTag",
592 "AssetTag");
Ed Tanous6c34de42018-08-29 13:37:36 -0700593 }
594 }
595 }
596 }
Ed Tanous6c34de42018-08-29 13:37:36 -0700597 },
598 "xyz.openbmc_project.ObjectMapper",
599 "/xyz/openbmc_project/object_mapper",
600 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
Ed Tanous66173382018-08-15 18:20:59 -0700601 "/xyz/openbmc_project/inventory", int32_t(0),
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500602 std::array<const char*, 5>{
Ed Tanous66173382018-08-15 18:20:59 -0700603 "xyz.openbmc_project.Inventory.Decorator.Asset",
604 "xyz.openbmc_project.Inventory.Item.Cpu",
605 "xyz.openbmc_project.Inventory.Item.Dimm",
606 "xyz.openbmc_project.Inventory.Item.System",
607 "xyz.openbmc_project.Common.UUID",
608 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700609}
610
611/**
Ed Tanous6c34de42018-08-29 13:37:36 -0700612 * @brief Retrieves host state properties over dbus
613 *
614 * @param[in] aResp Shared pointer for completing asynchronous calls.
615 *
616 * @return None.
617 */
zhanghch058d1b46d2021-04-01 11:18:24 +0800618inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
Ed Tanous6c34de42018-08-29 13:37:36 -0700619{
620 BMCWEB_LOG_DEBUG << "Get host information.";
621 crow::connections::systemBus->async_method_call(
Jennifer Leec5d03ff2019-03-08 15:42:58 -0800622 [aResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500623 const std::variant<std::string>& hostState) {
Ed Tanous6c34de42018-08-29 13:37:36 -0700624 if (ec)
625 {
626 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700627 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700628 return;
629 }
Ed Tanous66173382018-08-15 18:20:59 -0700630
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500631 const std::string* s = std::get_if<std::string>(&hostState);
Ed Tanous66173382018-08-15 18:20:59 -0700632 BMCWEB_LOG_DEBUG << "Host state: " << *s;
633 if (s != nullptr)
Ed Tanous6c34de42018-08-29 13:37:36 -0700634 {
Ed Tanous66173382018-08-15 18:20:59 -0700635 // Verify Host State
Andrew Geissler94732662019-01-08 19:32:16 -0800636 if (*s == "xyz.openbmc_project.State.Host.HostState.Running")
Ed Tanous6c34de42018-08-29 13:37:36 -0700637 {
Ed Tanous66173382018-08-15 18:20:59 -0700638 aResp->res.jsonValue["PowerState"] = "On";
639 aResp->res.jsonValue["Status"]["State"] = "Enabled";
640 }
Andrew Geissler83935af2020-02-13 10:24:53 -0600641 else if (*s == "xyz.openbmc_project.State.Host.HostState."
Gunnar Mills8c888602020-05-01 14:25:09 -0500642 "Quiesced")
643 {
644 aResp->res.jsonValue["PowerState"] = "On";
645 aResp->res.jsonValue["Status"]["State"] = "Quiesced";
646 }
647 else if (*s == "xyz.openbmc_project.State.Host.HostState."
Andrew Geissler83935af2020-02-13 10:24:53 -0600648 "DiagnosticMode")
649 {
650 aResp->res.jsonValue["PowerState"] = "On";
651 aResp->res.jsonValue["Status"]["State"] = "InTest";
652 }
Andrew Geissler1a2a1432021-01-06 13:48:57 -0600653 else if (*s == "xyz.openbmc_project.State.Host.HostState."
654 "TransitioningToRunning")
655 {
656 aResp->res.jsonValue["PowerState"] = "PoweringOn";
657 aResp->res.jsonValue["Status"]["State"] = "Disabled";
658 }
659 else if (*s == "xyz.openbmc_project.State.Host.HostState."
660 "TransitioningToOff")
661 {
662 aResp->res.jsonValue["PowerState"] = "PoweringOff";
663 aResp->res.jsonValue["Status"]["State"] = "Disabled";
664 }
Ed Tanous66173382018-08-15 18:20:59 -0700665 else
666 {
667 aResp->res.jsonValue["PowerState"] = "Off";
668 aResp->res.jsonValue["Status"]["State"] = "Disabled";
Ed Tanous6c34de42018-08-29 13:37:36 -0700669 }
670 }
671 },
672 "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
Ed Tanous66173382018-08-15 18:20:59 -0700673 "org.freedesktop.DBus.Properties", "Get",
674 "xyz.openbmc_project.State.Host", "CurrentHostState");
Ed Tanous6c34de42018-08-29 13:37:36 -0700675}
676
677/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500678 * @brief Translates boot source DBUS property value to redfish.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530679 *
680 * @param[in] dbusSource The boot source in DBUS speak.
681 *
682 * @return Returns as a string, the boot source in Redfish terms. If translation
683 * cannot be done, returns an empty string.
684 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000685inline std::string dbusToRfBootSource(const std::string& dbusSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530686{
687 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
688 {
689 return "None";
690 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700691 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530692 {
693 return "Hdd";
694 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700695 if (dbusSource ==
696 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530697 {
698 return "Cd";
699 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700700 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530701 {
702 return "Pxe";
703 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700704 if (dbusSource ==
705 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700706 {
707 return "Usb";
708 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700709 return "";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530710}
711
712/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500713 * @brief Translates boot mode DBUS property value to redfish.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530714 *
715 * @param[in] dbusMode The boot mode in DBUS speak.
716 *
717 * @return Returns as a string, the boot mode in Redfish terms. If translation
718 * cannot be done, returns an empty string.
719 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000720inline std::string dbusToRfBootMode(const std::string& dbusMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530721{
722 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
723 {
724 return "None";
725 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700726 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530727 {
728 return "Diags";
729 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700730 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530731 {
732 return "BiosSetup";
733 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700734 return "";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530735}
736
737/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500738 * @brief Translates boot source from Redfish to the DBus boot paths.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530739 *
740 * @param[in] rfSource The boot source in Redfish.
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700741 * @param[out] bootSource The DBus source
742 * @param[out] bootMode the DBus boot mode
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530743 *
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700744 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530745 */
zhanghch058d1b46d2021-04-01 11:18:24 +0800746inline int assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500747 const std::string& rfSource,
748 std::string& bootSource, std::string& bootMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530749{
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700750 // The caller has initialized the bootSource and bootMode to:
751 // bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
752 // bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
753 // Only modify the bootSource/bootMode variable needed to achieve the
754 // desired boot action.
755
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530756 if (rfSource == "None")
757 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700758 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530759 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700760 if (rfSource == "Pxe")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530761 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700762 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
763 }
764 else if (rfSource == "Hdd")
765 {
766 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
767 }
768 else if (rfSource == "Diags")
769 {
770 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
771 }
772 else if (rfSource == "Cd")
773 {
774 bootSource =
775 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
776 }
777 else if (rfSource == "BiosSetup")
778 {
779 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530780 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700781 else if (rfSource == "Usb")
782 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700783 bootSource =
784 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700785 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530786 else
787 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700788 BMCWEB_LOG_DEBUG << "Invalid property value for "
789 "BootSourceOverrideTarget: "
790 << bootSource;
791 messages::propertyValueNotInList(aResp->res, rfSource,
792 "BootSourceTargetOverride");
793 return -1;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530794 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700795 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530796}
Andrew Geissler978b8802020-11-19 13:36:40 -0600797/**
798 * @brief Retrieves boot progress of the system
799 *
800 * @param[in] aResp Shared pointer for generating response message.
801 *
802 * @return None.
803 */
zhanghch058d1b46d2021-04-01 11:18:24 +0800804inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
Andrew Geissler978b8802020-11-19 13:36:40 -0600805{
806 crow::connections::systemBus->async_method_call(
807 [aResp](const boost::system::error_code ec,
808 const std::variant<std::string>& bootProgress) {
809 if (ec)
810 {
811 // BootProgress is an optional object so just do nothing if
812 // not found
813 return;
814 }
815
816 const std::string* bootProgressStr =
817 std::get_if<std::string>(&bootProgress);
818
819 if (!bootProgressStr)
820 {
821 // Interface implemented but property not found, return error
822 // for that
823 messages::internalError(aResp->res);
824 return;
825 }
826
827 BMCWEB_LOG_DEBUG << "Boot Progress: " << *bootProgressStr;
828
829 // Now convert the D-Bus BootProgress to the appropriate Redfish
830 // enum
831 std::string rfBpLastState = "None";
832 if (*bootProgressStr == "xyz.openbmc_project.State.Boot.Progress."
833 "ProgressStages.Unspecified")
834 {
835 rfBpLastState = "None";
836 }
837 else if (*bootProgressStr ==
838 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
839 "PrimaryProcInit")
840 {
841 rfBpLastState = "PrimaryProcessorInitializationStarted";
842 }
843 else if (*bootProgressStr ==
844 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
845 "BusInit")
846 {
847 rfBpLastState = "BusInitializationStarted";
848 }
849 else if (*bootProgressStr ==
850 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
851 "MemoryInit")
852 {
853 rfBpLastState = "MemoryInitializationStarted";
854 }
855 else if (*bootProgressStr ==
856 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
857 "SecondaryProcInit")
858 {
859 rfBpLastState = "SecondaryProcessorInitializationStarted";
860 }
861 else if (*bootProgressStr ==
862 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
863 "PCIInit")
864 {
865 rfBpLastState = "PCIResourceConfigStarted";
866 }
867 else if (*bootProgressStr ==
868 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
869 "SystemInitComplete")
870 {
871 rfBpLastState = "SystemHardwareInitializationComplete";
872 }
873 else if (*bootProgressStr ==
874 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
875 "OSStart")
876 {
877 rfBpLastState = "OSBootStarted";
878 }
879 else if (*bootProgressStr ==
880 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
881 "OSRunning")
882 {
883 rfBpLastState = "OSRunning";
884 }
885 else
886 {
887 BMCWEB_LOG_DEBUG << "Unsupported D-Bus BootProgress "
888 << *bootProgressStr;
889 // Just return the default
890 }
891
892 aResp->res.jsonValue["BootProgress"]["LastState"] = rfBpLastState;
893 },
894 "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
895 "org.freedesktop.DBus.Properties", "Get",
896 "xyz.openbmc_project.State.Boot.Progress", "BootProgress");
897}
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530898
899/**
900 * @brief Retrieves boot mode over DBUS and fills out the response
901 *
902 * @param[in] aResp Shared pointer for generating response message.
903 * @param[in] bootDbusObj The dbus object to query for boot properties.
904 *
905 * @return None.
906 */
zhanghch058d1b46d2021-04-01 11:18:24 +0800907inline void getBootMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Ed Tanousb5a76932020-09-29 16:16:58 -0700908 const std::string& bootDbusObj)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530909{
910 crow::connections::systemBus->async_method_call(
911 [aResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500912 const std::variant<std::string>& bootMode) {
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530913 if (ec)
914 {
915 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
916 messages::internalError(aResp->res);
917 return;
918 }
919
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500920 const std::string* bootModeStr =
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530921 std::get_if<std::string>(&bootMode);
922
923 if (!bootModeStr)
924 {
925 messages::internalError(aResp->res);
926 return;
927 }
928
929 BMCWEB_LOG_DEBUG << "Boot mode: " << *bootModeStr;
930
931 // TODO (Santosh): Do we need to support override mode?
932 aResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = "Legacy";
933 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget@Redfish."
934 "AllowableValues"] = {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700935 "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530936
937 if (*bootModeStr !=
938 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
939 {
940 auto rfMode = dbusToRfBootMode(*bootModeStr);
941 if (!rfMode.empty())
942 {
943 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
944 rfMode;
945 }
946 }
947
948 // If the BootSourceOverrideTarget is still "None" at the end,
949 // reset the BootSourceOverrideEnabled to indicate that
950 // overrides are disabled
951 if (aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] ==
952 "None")
953 {
954 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
955 "Disabled";
956 }
957 },
958 "xyz.openbmc_project.Settings", bootDbusObj,
959 "org.freedesktop.DBus.Properties", "Get",
960 "xyz.openbmc_project.Control.Boot.Mode", "BootMode");
961}
962
963/**
964 * @brief Retrieves boot source over DBUS
965 *
966 * @param[in] aResp Shared pointer for generating response message.
967 * @param[in] oneTimeEnable Boolean to indicate boot properties are one-time.
968 *
969 * @return None.
970 */
zhanghch058d1b46d2021-04-01 11:18:24 +0800971inline void getBootSource(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Ed Tanousf23b7292020-10-15 09:41:17 -0700972 bool oneTimeEnabled)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530973{
974 std::string bootDbusObj =
975 oneTimeEnabled ? "/xyz/openbmc_project/control/host0/boot/one_time"
976 : "/xyz/openbmc_project/control/host0/boot";
977
978 BMCWEB_LOG_DEBUG << "Is one time: " << oneTimeEnabled;
979 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
980 (oneTimeEnabled) ? "Once" : "Continuous";
981
982 crow::connections::systemBus->async_method_call(
983 [aResp, bootDbusObj](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500984 const std::variant<std::string>& bootSource) {
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530985 if (ec)
986 {
987 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
988 messages::internalError(aResp->res);
989 return;
990 }
991
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500992 const std::string* bootSourceStr =
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530993 std::get_if<std::string>(&bootSource);
994
995 if (!bootSourceStr)
996 {
997 messages::internalError(aResp->res);
998 return;
999 }
1000 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSourceStr;
1001
1002 auto rfSource = dbusToRfBootSource(*bootSourceStr);
1003 if (!rfSource.empty())
1004 {
1005 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
1006 rfSource;
1007 }
1008 },
1009 "xyz.openbmc_project.Settings", bootDbusObj,
1010 "org.freedesktop.DBus.Properties", "Get",
1011 "xyz.openbmc_project.Control.Boot.Source", "BootSource");
Ed Tanousf23b7292020-10-15 09:41:17 -07001012 getBootMode(aResp, bootDbusObj);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301013}
1014
1015/**
1016 * @brief Retrieves "One time" enabled setting over DBUS and calls function to
1017 * get boot source and boot mode.
1018 *
1019 * @param[in] aResp Shared pointer for generating response message.
1020 *
1021 * @return None.
1022 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001023inline void getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301024{
1025 BMCWEB_LOG_DEBUG << "Get boot information.";
1026
1027 crow::connections::systemBus->async_method_call(
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001028 [aResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001029 const std::variant<bool>& oneTime) {
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301030 if (ec)
1031 {
1032 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
James Feist2a833c72019-07-19 10:17:13 -07001033 // not an error, don't have to have the interface
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301034 return;
1035 }
1036
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001037 const bool* oneTimePtr = std::get_if<bool>(&oneTime);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301038
1039 if (!oneTimePtr)
1040 {
1041 messages::internalError(aResp->res);
1042 return;
1043 }
1044 getBootSource(aResp, *oneTimePtr);
1045 },
1046 "xyz.openbmc_project.Settings",
1047 "/xyz/openbmc_project/control/host0/boot/one_time",
1048 "org.freedesktop.DBus.Properties", "Get",
1049 "xyz.openbmc_project.Object.Enable", "Enabled");
1050}
1051
1052/**
Gunnar Millsc0557e12020-06-30 11:26:20 -05001053 * @brief Retrieves the Last Reset Time
1054 *
1055 * "Reset" is an overloaded term in Redfish, "Reset" includes power on
1056 * and power off. Even though this is the "system" Redfish object look at the
1057 * chassis D-Bus interface for the LastStateChangeTime since this has the
1058 * last power operation time.
1059 *
1060 * @param[in] aResp Shared pointer for generating response message.
1061 *
1062 * @return None.
1063 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001064inline void getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
Gunnar Millsc0557e12020-06-30 11:26:20 -05001065{
1066 BMCWEB_LOG_DEBUG << "Getting System Last Reset Time";
1067
1068 crow::connections::systemBus->async_method_call(
1069 [aResp](const boost::system::error_code ec,
1070 std::variant<uint64_t>& lastResetTime) {
1071 if (ec)
1072 {
1073 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
1074 return;
1075 }
1076
1077 const uint64_t* lastResetTimePtr =
1078 std::get_if<uint64_t>(&lastResetTime);
1079
1080 if (!lastResetTimePtr)
1081 {
1082 messages::internalError(aResp->res);
1083 return;
1084 }
1085 // LastStateChangeTime is epoch time, in milliseconds
1086 // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
1087 time_t lastResetTimeStamp =
1088 static_cast<time_t>(*lastResetTimePtr / 1000);
1089
1090 // Convert to ISO 8601 standard
1091 aResp->res.jsonValue["LastResetTime"] =
1092 crow::utility::getDateTime(lastResetTimeStamp);
1093 },
1094 "xyz.openbmc_project.State.Chassis",
1095 "/xyz/openbmc_project/state/chassis0",
1096 "org.freedesktop.DBus.Properties", "Get",
1097 "xyz.openbmc_project.State.Chassis", "LastStateChangeTime");
1098}
1099
1100/**
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001101 * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
1102 *
1103 * @param[in] aResp Shared pointer for generating response message.
1104 *
1105 * @return None.
1106 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001107inline void getAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001108{
1109 BMCWEB_LOG_DEBUG << "Get Automatic Retry policy";
1110
1111 crow::connections::systemBus->async_method_call(
1112 [aResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001113 std::variant<bool>& autoRebootEnabled) {
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001114 if (ec)
1115 {
1116 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
1117 return;
1118 }
1119
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001120 const bool* autoRebootEnabledPtr =
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001121 std::get_if<bool>(&autoRebootEnabled);
1122
1123 if (!autoRebootEnabledPtr)
1124 {
1125 messages::internalError(aResp->res);
1126 return;
1127 }
1128
1129 BMCWEB_LOG_DEBUG << "Auto Reboot: " << *autoRebootEnabledPtr;
1130 if (*autoRebootEnabledPtr == true)
1131 {
1132 aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
1133 "RetryAttempts";
1134 // If AutomaticRetry (AutoReboot) is enabled see how many
1135 // attempts are left
1136 crow::connections::systemBus->async_method_call(
Ed Tanouscb13a392020-07-25 19:02:03 +00001137 [aResp](const boost::system::error_code ec2,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001138 std::variant<uint32_t>& autoRebootAttemptsLeft) {
Ed Tanouscb13a392020-07-25 19:02:03 +00001139 if (ec2)
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001140 {
Ed Tanouscb13a392020-07-25 19:02:03 +00001141 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec2;
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001142 return;
1143 }
1144
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001145 const uint32_t* autoRebootAttemptsLeftPtr =
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001146 std::get_if<uint32_t>(&autoRebootAttemptsLeft);
1147
1148 if (!autoRebootAttemptsLeftPtr)
1149 {
1150 messages::internalError(aResp->res);
1151 return;
1152 }
1153
1154 BMCWEB_LOG_DEBUG << "Auto Reboot Attempts Left: "
1155 << *autoRebootAttemptsLeftPtr;
1156
1157 aResp->res
1158 .jsonValue["Boot"]
1159 ["RemainingAutomaticRetryAttempts"] =
1160 *autoRebootAttemptsLeftPtr;
1161 },
1162 "xyz.openbmc_project.State.Host",
1163 "/xyz/openbmc_project/state/host0",
1164 "org.freedesktop.DBus.Properties", "Get",
1165 "xyz.openbmc_project.Control.Boot.RebootAttempts",
1166 "AttemptsLeft");
1167 }
1168 else
1169 {
1170 aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
1171 "Disabled";
1172 }
1173
1174 // Not on D-Bus. Hardcoded here:
1175 // https://github.com/openbmc/phosphor-state-manager/blob/1dbbef42675e94fb1f78edb87d6b11380260535a/meson_options.txt#L71
1176 aResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] = 3;
Gunnar Mills69f35302020-05-17 16:06:31 -05001177
1178 // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
1179 // and RetryAttempts. OpenBMC only supports Disabled and
1180 // RetryAttempts.
1181 aResp->res.jsonValue["Boot"]["AutomaticRetryConfig@Redfish."
1182 "AllowableValues"] = {"Disabled",
1183 "RetryAttempts"};
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001184 },
1185 "xyz.openbmc_project.Settings",
1186 "/xyz/openbmc_project/control/host0/auto_reboot",
1187 "org.freedesktop.DBus.Properties", "Get",
1188 "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot");
1189}
1190
1191/**
George Liuc6a620f2020-04-10 17:18:11 +08001192 * @brief Retrieves power restore policy over DBUS.
1193 *
1194 * @param[in] aResp Shared pointer for generating response message.
1195 *
1196 * @return None.
1197 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001198inline void
1199 getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
George Liuc6a620f2020-04-10 17:18:11 +08001200{
1201 BMCWEB_LOG_DEBUG << "Get power restore policy";
1202
1203 crow::connections::systemBus->async_method_call(
1204 [aResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001205 std::variant<std::string>& policy) {
George Liuc6a620f2020-04-10 17:18:11 +08001206 if (ec)
1207 {
1208 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1209 return;
1210 }
1211
1212 const boost::container::flat_map<std::string, std::string>
1213 policyMaps = {
1214 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1215 "AlwaysOn",
1216 "AlwaysOn"},
1217 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1218 "AlwaysOff",
1219 "AlwaysOff"},
1220 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
Gunnar Mills37ec9072021-01-05 19:43:44 -06001221 "Restore",
George Liuc6a620f2020-04-10 17:18:11 +08001222 "LastState"}};
1223
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001224 const std::string* policyPtr = std::get_if<std::string>(&policy);
George Liuc6a620f2020-04-10 17:18:11 +08001225
1226 if (!policyPtr)
1227 {
1228 messages::internalError(aResp->res);
1229 return;
1230 }
1231
1232 auto policyMapsIt = policyMaps.find(*policyPtr);
1233 if (policyMapsIt == policyMaps.end())
1234 {
1235 messages::internalError(aResp->res);
1236 return;
1237 }
1238
1239 aResp->res.jsonValue["PowerRestorePolicy"] = policyMapsIt->second;
1240 },
1241 "xyz.openbmc_project.Settings",
1242 "/xyz/openbmc_project/control/host0/power_restore_policy",
1243 "org.freedesktop.DBus.Properties", "Get",
1244 "xyz.openbmc_project.Control.Power.RestorePolicy",
1245 "PowerRestorePolicy");
1246}
1247
1248/**
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301249 * @brief Sets boot properties into DBUS object(s).
1250 *
1251 * @param[in] aResp Shared pointer for generating response message.
1252 * @param[in] oneTimeEnabled Is "one-time" setting already enabled.
1253 * @param[in] bootSource The boot source to set.
1254 * @param[in] bootEnable The source override "enable" to set.
1255 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001256 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301257 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001258inline void setBootModeOrSource(std::shared_ptr<bmcweb::AsyncResp> aResp,
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301259 bool oneTimeEnabled,
Ed Tanousf23b7292020-10-15 09:41:17 -07001260 const std::optional<std::string>& bootSource,
1261 const std::optional<std::string>& bootEnable)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301262{
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001263 std::string bootSourceStr =
1264 "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
1265 std::string bootModeStr =
1266 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301267 bool oneTimeSetting = oneTimeEnabled;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001268 bool useBootSource = true;
1269
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301270 // Validate incoming parameters
1271 if (bootEnable)
1272 {
1273 if (*bootEnable == "Once")
1274 {
1275 oneTimeSetting = true;
1276 }
1277 else if (*bootEnable == "Continuous")
1278 {
1279 oneTimeSetting = false;
1280 }
1281 else if (*bootEnable == "Disabled")
1282 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001283 BMCWEB_LOG_DEBUG << "Boot source override will be disabled";
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301284 oneTimeSetting = false;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001285 useBootSource = false;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301286 }
1287 else
1288 {
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301289 BMCWEB_LOG_DEBUG << "Unsupported value for "
1290 "BootSourceOverrideEnabled: "
1291 << *bootEnable;
1292 messages::propertyValueNotInList(aResp->res, *bootEnable,
1293 "BootSourceOverrideEnabled");
1294 return;
1295 }
1296 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301297
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001298 if (bootSource && useBootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301299 {
1300 // Source target specified
1301 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource;
1302 // Figure out which DBUS interface and property to use
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001303 if (assignBootParameters(aResp, *bootSource, bootSourceStr,
1304 bootModeStr))
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301305 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001306 BMCWEB_LOG_DEBUG
1307 << "Invalid property value for BootSourceOverrideTarget: "
1308 << *bootSource;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301309 messages::propertyValueNotInList(aResp->res, *bootSource,
1310 "BootSourceTargetOverride");
1311 return;
1312 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001313 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301314
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001315 // Act on validated parameters
1316 BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
1317 BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001318 const char* bootObj =
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001319 oneTimeSetting ? "/xyz/openbmc_project/control/host0/boot/one_time"
1320 : "/xyz/openbmc_project/control/host0/boot";
1321
1322 crow::connections::systemBus->async_method_call(
1323 [aResp](const boost::system::error_code ec) {
1324 if (ec)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301325 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001326 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1327 messages::internalError(aResp->res);
1328 return;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301329 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001330 BMCWEB_LOG_DEBUG << "Boot source update done.";
1331 },
1332 "xyz.openbmc_project.Settings", bootObj,
1333 "org.freedesktop.DBus.Properties", "Set",
1334 "xyz.openbmc_project.Control.Boot.Source", "BootSource",
1335 std::variant<std::string>(bootSourceStr));
1336
1337 crow::connections::systemBus->async_method_call(
1338 [aResp](const boost::system::error_code ec) {
1339 if (ec)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301340 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001341 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1342 messages::internalError(aResp->res);
1343 return;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301344 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001345 BMCWEB_LOG_DEBUG << "Boot mode update done.";
1346 },
1347 "xyz.openbmc_project.Settings", bootObj,
1348 "org.freedesktop.DBus.Properties", "Set",
1349 "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
1350 std::variant<std::string>(bootModeStr));
1351
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301352 crow::connections::systemBus->async_method_call(
1353 [aResp{std::move(aResp)}](const boost::system::error_code ec) {
1354 if (ec)
1355 {
1356 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1357 messages::internalError(aResp->res);
1358 return;
1359 }
1360 BMCWEB_LOG_DEBUG << "Boot enable update done.";
1361 },
1362 "xyz.openbmc_project.Settings",
1363 "/xyz/openbmc_project/control/host0/boot/one_time",
1364 "org.freedesktop.DBus.Properties", "Set",
1365 "xyz.openbmc_project.Object.Enable", "Enabled",
1366 std::variant<bool>(oneTimeSetting));
1367}
1368
1369/**
1370 * @brief Retrieves "One time" enabled setting over DBUS and calls function to
1371 * set boot source/boot mode properties.
1372 *
1373 * @param[in] aResp Shared pointer for generating response message.
1374 * @param[in] bootSource The boot source from incoming RF request.
1375 * @param[in] bootEnable The boot override enable from incoming RF request.
1376 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001377 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301378 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001379inline void
1380 setBootSourceProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1381 std::optional<std::string> bootSource,
1382 std::optional<std::string> bootEnable)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301383{
1384 BMCWEB_LOG_DEBUG << "Set boot information.";
1385
1386 crow::connections::systemBus->async_method_call(
Johnathan Mantey265c1602019-08-08 11:02:51 -07001387 [aResp, bootSource{std::move(bootSource)},
Patrick Williams19bd78d2020-05-13 17:38:24 -05001388 bootEnable{std::move(bootEnable)}](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001389 const std::variant<bool>& oneTime) {
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301390 if (ec)
1391 {
1392 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1393 messages::internalError(aResp->res);
1394 return;
1395 }
1396
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001397 const bool* oneTimePtr = std::get_if<bool>(&oneTime);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301398
1399 if (!oneTimePtr)
1400 {
1401 messages::internalError(aResp->res);
1402 return;
1403 }
1404
1405 BMCWEB_LOG_DEBUG << "Got one time: " << *oneTimePtr;
1406
Ed Tanousf23b7292020-10-15 09:41:17 -07001407 setBootModeOrSource(aResp, *oneTimePtr, bootSource, bootEnable);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301408 },
1409 "xyz.openbmc_project.Settings",
1410 "/xyz/openbmc_project/control/host0/boot/one_time",
1411 "org.freedesktop.DBus.Properties", "Get",
1412 "xyz.openbmc_project.Object.Enable", "Enabled");
1413}
1414
George Liuc6a620f2020-04-10 17:18:11 +08001415/**
Gunnar Mills98e386e2020-10-30 14:58:09 -05001416 * @brief Sets AssetTag
1417 *
1418 * @param[in] aResp Shared pointer for generating response message.
1419 * @param[in] assetTag "AssetTag" from request.
1420 *
1421 * @return None.
1422 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001423inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Gunnar Mills98e386e2020-10-30 14:58:09 -05001424 const std::string& assetTag)
1425{
1426 crow::connections::systemBus->async_method_call(
1427 [aResp, assetTag](
1428 const boost::system::error_code ec,
1429 const std::vector<std::pair<
1430 std::string,
1431 std::vector<std::pair<std::string, std::vector<std::string>>>>>&
1432 subtree) {
1433 if (ec)
1434 {
1435 BMCWEB_LOG_DEBUG << "D-Bus response error on GetSubTree " << ec;
1436 messages::internalError(aResp->res);
1437 return;
1438 }
1439 if (subtree.size() == 0)
1440 {
1441 BMCWEB_LOG_DEBUG << "Can't find system D-Bus object!";
1442 messages::internalError(aResp->res);
1443 return;
1444 }
1445 // Assume only 1 system D-Bus object
1446 // Throw an error if there is more than 1
1447 if (subtree.size() > 1)
1448 {
1449 BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus object!";
1450 messages::internalError(aResp->res);
1451 return;
1452 }
1453 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1454 {
1455 BMCWEB_LOG_DEBUG << "Asset Tag Set mapper error!";
1456 messages::internalError(aResp->res);
1457 return;
1458 }
1459
1460 const std::string& path = subtree[0].first;
1461 const std::string& service = subtree[0].second.begin()->first;
1462
1463 if (service.empty())
1464 {
1465 BMCWEB_LOG_DEBUG << "Asset Tag Set service mapper error!";
1466 messages::internalError(aResp->res);
1467 return;
1468 }
1469
1470 crow::connections::systemBus->async_method_call(
1471 [aResp](const boost::system::error_code ec2) {
1472 if (ec2)
1473 {
1474 BMCWEB_LOG_DEBUG
1475 << "D-Bus response error on AssetTag Set " << ec2;
1476 messages::internalError(aResp->res);
1477 return;
1478 }
1479 },
1480 service, path, "org.freedesktop.DBus.Properties", "Set",
1481 "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag",
1482 std::variant<std::string>(assetTag));
1483 },
1484 "xyz.openbmc_project.ObjectMapper",
1485 "/xyz/openbmc_project/object_mapper",
1486 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
1487 "/xyz/openbmc_project/inventory", int32_t(0),
1488 std::array<const char*, 1>{
1489 "xyz.openbmc_project.Inventory.Item.System"});
1490}
1491
1492/**
Gunnar Mills69f35302020-05-17 16:06:31 -05001493 * @brief Sets automaticRetry (Auto Reboot)
1494 *
1495 * @param[in] aResp Shared pointer for generating response message.
1496 * @param[in] automaticRetryConfig "AutomaticRetryConfig" from request.
1497 *
1498 * @return None.
1499 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001500inline void setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Ed Tanousf23b7292020-10-15 09:41:17 -07001501 const std::string& automaticRetryConfig)
Gunnar Mills69f35302020-05-17 16:06:31 -05001502{
1503 BMCWEB_LOG_DEBUG << "Set Automatic Retry.";
1504
1505 // OpenBMC only supports "Disabled" and "RetryAttempts".
1506 bool autoRebootEnabled;
1507
1508 if (automaticRetryConfig == "Disabled")
1509 {
1510 autoRebootEnabled = false;
1511 }
1512 else if (automaticRetryConfig == "RetryAttempts")
1513 {
1514 autoRebootEnabled = true;
1515 }
1516 else
1517 {
1518 BMCWEB_LOG_DEBUG << "Invalid property value for "
1519 "AutomaticRetryConfig: "
1520 << automaticRetryConfig;
1521 messages::propertyValueNotInList(aResp->res, automaticRetryConfig,
1522 "AutomaticRetryConfig");
1523 return;
1524 }
1525
1526 crow::connections::systemBus->async_method_call(
1527 [aResp](const boost::system::error_code ec) {
1528 if (ec)
1529 {
1530 messages::internalError(aResp->res);
1531 return;
1532 }
1533 },
1534 "xyz.openbmc_project.Settings",
1535 "/xyz/openbmc_project/control/host0/auto_reboot",
1536 "org.freedesktop.DBus.Properties", "Set",
1537 "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
1538 std::variant<bool>(autoRebootEnabled));
1539}
1540
1541/**
George Liuc6a620f2020-04-10 17:18:11 +08001542 * @brief Sets power restore policy properties.
1543 *
1544 * @param[in] aResp Shared pointer for generating response message.
1545 * @param[in] policy power restore policy properties from request.
1546 *
1547 * @return None.
1548 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001549inline void
1550 setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1551 const std::string& policy)
George Liuc6a620f2020-04-10 17:18:11 +08001552{
1553 BMCWEB_LOG_DEBUG << "Set power restore policy.";
1554
1555 const boost::container::flat_map<std::string, std::string> policyMaps = {
1556 {"AlwaysOn", "xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1557 "AlwaysOn"},
1558 {"AlwaysOff", "xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1559 "AlwaysOff"},
1560 {"LastState", "xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
Gunnar Mills37ec9072021-01-05 19:43:44 -06001561 "Restore"}};
George Liuc6a620f2020-04-10 17:18:11 +08001562
1563 std::string powerRestorPolicy;
1564
Gunnar Mills4e69c902021-01-05 19:50:11 -06001565 auto policyMapsIt = policyMaps.find(policy);
George Liuc6a620f2020-04-10 17:18:11 +08001566 if (policyMapsIt == policyMaps.end())
1567 {
Gunnar Mills4e69c902021-01-05 19:50:11 -06001568 messages::propertyValueNotInList(aResp->res, policy,
1569 "PowerRestorePolicy");
George Liuc6a620f2020-04-10 17:18:11 +08001570 return;
1571 }
1572
1573 powerRestorPolicy = policyMapsIt->second;
1574
1575 crow::connections::systemBus->async_method_call(
1576 [aResp](const boost::system::error_code ec) {
1577 if (ec)
1578 {
1579 messages::internalError(aResp->res);
1580 return;
1581 }
1582 },
1583 "xyz.openbmc_project.Settings",
1584 "/xyz/openbmc_project/control/host0/power_restore_policy",
1585 "org.freedesktop.DBus.Properties", "Set",
1586 "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
1587 std::variant<std::string>(powerRestorPolicy));
1588}
1589
AppaRao Pulia6349912019-10-18 17:16:08 +05301590#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1591/**
1592 * @brief Retrieves provisioning status
1593 *
1594 * @param[in] aResp Shared pointer for completing asynchronous calls.
1595 *
1596 * @return None.
1597 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001598inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> aResp)
AppaRao Pulia6349912019-10-18 17:16:08 +05301599{
1600 BMCWEB_LOG_DEBUG << "Get OEM information.";
1601 crow::connections::systemBus->async_method_call(
1602 [aResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001603 const std::vector<std::pair<std::string, VariantType>>&
1604 propertiesList) {
AppaRao Pulib99fb1a2020-07-08 16:42:48 +05301605 nlohmann::json& oemPFR =
1606 aResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
James Feist50626f42020-09-23 14:40:47 -07001607 aResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
1608 "#OemComputerSystem.OpenBmc";
1609 oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning";
1610
AppaRao Pulia6349912019-10-18 17:16:08 +05301611 if (ec)
1612 {
1613 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
AppaRao Pulib99fb1a2020-07-08 16:42:48 +05301614 // not an error, don't have to have the interface
1615 oemPFR["ProvisioningStatus"] = "NotProvisioned";
AppaRao Pulia6349912019-10-18 17:16:08 +05301616 return;
1617 }
1618
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001619 const bool* provState = nullptr;
1620 const bool* lockState = nullptr;
1621 for (const std::pair<std::string, VariantType>& property :
AppaRao Pulia6349912019-10-18 17:16:08 +05301622 propertiesList)
1623 {
1624 if (property.first == "UfmProvisioned")
1625 {
1626 provState = std::get_if<bool>(&property.second);
1627 }
1628 else if (property.first == "UfmLocked")
1629 {
1630 lockState = std::get_if<bool>(&property.second);
1631 }
1632 }
1633
1634 if ((provState == nullptr) || (lockState == nullptr))
1635 {
1636 BMCWEB_LOG_DEBUG << "Unable to get PFR attributes.";
1637 messages::internalError(aResp->res);
1638 return;
1639 }
1640
AppaRao Pulia6349912019-10-18 17:16:08 +05301641 if (*provState == true)
1642 {
1643 if (*lockState == true)
1644 {
1645 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
1646 }
1647 else
1648 {
1649 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
1650 }
1651 }
1652 else
1653 {
1654 oemPFR["ProvisioningStatus"] = "NotProvisioned";
1655 }
1656 },
1657 "xyz.openbmc_project.PFR.Manager", "/xyz/openbmc_project/pfr",
1658 "org.freedesktop.DBus.Properties", "GetAll",
1659 "xyz.openbmc_project.PFR.Attributes");
1660}
1661#endif
1662
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301663/**
Yong Li51709ff2019-09-30 14:13:04 +08001664 * @brief Translates watchdog timeout action DBUS property value to redfish.
1665 *
1666 * @param[in] dbusAction The watchdog timeout action in D-BUS.
1667 *
1668 * @return Returns as a string, the timeout action in Redfish terms. If
1669 * translation cannot be done, returns an empty string.
1670 */
Ed Tanous23a21a12020-07-25 04:45:05 +00001671inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
Yong Li51709ff2019-09-30 14:13:04 +08001672{
1673 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
1674 {
1675 return "None";
1676 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07001677 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
Yong Li51709ff2019-09-30 14:13:04 +08001678 {
1679 return "ResetSystem";
1680 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07001681 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
Yong Li51709ff2019-09-30 14:13:04 +08001682 {
1683 return "PowerDown";
1684 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07001685 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
Yong Li51709ff2019-09-30 14:13:04 +08001686 {
1687 return "PowerCycle";
1688 }
1689
1690 return "";
1691}
1692
1693/**
Yong Lic45f0082019-10-10 14:19:01 +08001694 *@brief Translates timeout action from Redfish to DBUS property value.
1695 *
1696 *@param[in] rfAction The timeout action in Redfish.
1697 *
1698 *@return Returns as a string, the time_out action as expected by DBUS.
1699 *If translation cannot be done, returns an empty string.
1700 */
1701
Ed Tanous23a21a12020-07-25 04:45:05 +00001702inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
Yong Lic45f0082019-10-10 14:19:01 +08001703{
1704 if (rfAction == "None")
1705 {
1706 return "xyz.openbmc_project.State.Watchdog.Action.None";
1707 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07001708 if (rfAction == "PowerCycle")
Yong Lic45f0082019-10-10 14:19:01 +08001709 {
1710 return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
1711 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07001712 if (rfAction == "PowerDown")
Yong Lic45f0082019-10-10 14:19:01 +08001713 {
1714 return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
1715 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07001716 if (rfAction == "ResetSystem")
Yong Lic45f0082019-10-10 14:19:01 +08001717 {
1718 return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
1719 }
1720
1721 return "";
1722}
1723
1724/**
Yong Li51709ff2019-09-30 14:13:04 +08001725 * @brief Retrieves host watchdog timer properties over DBUS
1726 *
1727 * @param[in] aResp Shared pointer for completing asynchronous calls.
1728 *
1729 * @return None.
1730 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001731inline void
1732 getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
Yong Li51709ff2019-09-30 14:13:04 +08001733{
1734 BMCWEB_LOG_DEBUG << "Get host watchodg";
1735 crow::connections::systemBus->async_method_call(
1736 [aResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001737 PropertiesType& properties) {
Yong Li51709ff2019-09-30 14:13:04 +08001738 if (ec)
1739 {
1740 // watchdog service is stopped
1741 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1742 return;
1743 }
1744
1745 BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop.";
1746
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001747 nlohmann::json& hostWatchdogTimer =
Yong Li51709ff2019-09-30 14:13:04 +08001748 aResp->res.jsonValue["HostWatchdogTimer"];
1749
1750 // watchdog service is running/enabled
1751 hostWatchdogTimer["Status"]["State"] = "Enabled";
1752
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001753 for (const auto& property : properties)
Yong Li51709ff2019-09-30 14:13:04 +08001754 {
1755 BMCWEB_LOG_DEBUG << "prop=" << property.first;
1756 if (property.first == "Enabled")
1757 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001758 const bool* state = std::get_if<bool>(&property.second);
Yong Li51709ff2019-09-30 14:13:04 +08001759
1760 if (!state)
1761 {
1762 messages::internalError(aResp->res);
1763 continue;
1764 }
1765
1766 hostWatchdogTimer["FunctionEnabled"] = *state;
1767 }
1768 else if (property.first == "ExpireAction")
1769 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001770 const std::string* s =
Yong Li51709ff2019-09-30 14:13:04 +08001771 std::get_if<std::string>(&property.second);
1772 if (!s)
1773 {
1774 messages::internalError(aResp->res);
1775 continue;
1776 }
1777
1778 std::string action = dbusToRfWatchdogAction(*s);
1779 if (action.empty())
1780 {
1781 messages::internalError(aResp->res);
1782 continue;
1783 }
1784 hostWatchdogTimer["TimeoutAction"] = action;
1785 }
1786 }
1787 },
1788 "xyz.openbmc_project.Watchdog", "/xyz/openbmc_project/watchdog/host0",
1789 "org.freedesktop.DBus.Properties", "GetAll",
1790 "xyz.openbmc_project.State.Watchdog");
1791}
1792
1793/**
Yong Lic45f0082019-10-10 14:19:01 +08001794 * @brief Sets Host WatchDog Timer properties.
1795 *
1796 * @param[in] aResp Shared pointer for generating response message.
1797 * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming
1798 * RF request.
1799 * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
1800 *
1801 * @return None.
1802 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001803inline void setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Yong Lic45f0082019-10-10 14:19:01 +08001804 const std::optional<bool> wdtEnable,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001805 const std::optional<std::string>& wdtTimeOutAction)
Yong Lic45f0082019-10-10 14:19:01 +08001806{
1807 BMCWEB_LOG_DEBUG << "Set host watchdog";
1808
1809 if (wdtTimeOutAction)
1810 {
1811 std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
1812 // check if TimeOut Action is Valid
1813 if (wdtTimeOutActStr.empty())
1814 {
1815 BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: "
1816 << *wdtTimeOutAction;
1817 messages::propertyValueNotInList(aResp->res, *wdtTimeOutAction,
1818 "TimeoutAction");
1819 return;
1820 }
1821
1822 crow::connections::systemBus->async_method_call(
1823 [aResp](const boost::system::error_code ec) {
1824 if (ec)
1825 {
1826 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1827 messages::internalError(aResp->res);
1828 return;
1829 }
1830 },
1831 "xyz.openbmc_project.Watchdog",
1832 "/xyz/openbmc_project/watchdog/host0",
1833 "org.freedesktop.DBus.Properties", "Set",
1834 "xyz.openbmc_project.State.Watchdog", "ExpireAction",
1835 std::variant<std::string>(wdtTimeOutActStr));
1836 }
1837
1838 if (wdtEnable)
1839 {
1840 crow::connections::systemBus->async_method_call(
1841 [aResp](const boost::system::error_code ec) {
1842 if (ec)
1843 {
1844 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1845 messages::internalError(aResp->res);
1846 return;
1847 }
1848 },
1849 "xyz.openbmc_project.Watchdog",
1850 "/xyz/openbmc_project/watchdog/host0",
1851 "org.freedesktop.DBus.Properties", "Set",
1852 "xyz.openbmc_project.State.Watchdog", "Enabled",
1853 std::variant<bool>(*wdtEnable));
1854 }
1855}
1856
1857/**
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001858 * SystemsCollection derived class for delivering ComputerSystems Collection
1859 * Schema
1860 */
Ed Tanous1abe55e2018-09-05 08:30:59 -07001861class SystemsCollection : public Node
1862{
1863 public:
Ed Tanous52cc1122020-07-18 13:51:21 -07001864 SystemsCollection(App& app) : Node(app, "/redfish/v1/Systems/")
Ed Tanous1abe55e2018-09-05 08:30:59 -07001865 {
Ed Tanous1abe55e2018-09-05 08:30:59 -07001866 entityPrivileges = {
1867 {boost::beast::http::verb::get, {{"Login"}}},
1868 {boost::beast::http::verb::head, {{"Login"}}},
1869 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1870 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1871 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1872 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1873 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001874
Ed Tanous1abe55e2018-09-05 08:30:59 -07001875 private:
zhanghch058d1b46d2021-04-01 11:18:24 +08001876 void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1877 const crow::Request& req,
Ed Tanouscb13a392020-07-25 19:02:03 +00001878 const std::vector<std::string>&) override
Ed Tanous1abe55e2018-09-05 08:30:59 -07001879 {
zhanghch058d1b46d2021-04-01 11:18:24 +08001880 asyncResp->res.jsonValue["@odata.type"] =
Ed Tanous0f74e642018-11-12 15:17:05 -08001881 "#ComputerSystemCollection.ComputerSystemCollection";
zhanghch058d1b46d2021-04-01 11:18:24 +08001882 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
1883 asyncResp->res.jsonValue["Name"] = "Computer System Collection";
Sunitha Harish462023a2020-02-19 08:34:59 -06001884
1885 crow::connections::systemBus->async_method_call(
zhanghch058d1b46d2021-04-01 11:18:24 +08001886 [asyncResp, &req](const boost::system::error_code ec,
1887 const std::variant<std::string>& /*hostName*/) {
Ed Tanous2c70f802020-09-28 14:29:23 -07001888 nlohmann::json& ifaceArray =
Sunitha Harish462023a2020-02-19 08:34:59 -06001889 asyncResp->res.jsonValue["Members"];
Ed Tanous2c70f802020-09-28 14:29:23 -07001890 ifaceArray = nlohmann::json::array();
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001891 auto& count = asyncResp->res.jsonValue["Members@odata.count"];
Ed Tanous2c70f802020-09-28 14:29:23 -07001892 ifaceArray.push_back(
Ed Tanouscb13a392020-07-25 19:02:03 +00001893 {{"@odata.id", "/redfish/v1/Systems/system"}});
Tim Lee94bda602020-11-19 14:14:27 +08001894 count = ifaceArray.size();
Ed Tanouscb13a392020-07-25 19:02:03 +00001895 if (!ec)
Sunitha Harish462023a2020-02-19 08:34:59 -06001896 {
Ed Tanouscb13a392020-07-25 19:02:03 +00001897 BMCWEB_LOG_DEBUG << "Hypervisor is available";
Ed Tanous2c70f802020-09-28 14:29:23 -07001898 ifaceArray.push_back(
Ed Tanouscb13a392020-07-25 19:02:03 +00001899 {{"@odata.id", "/redfish/v1/Systems/hypervisor"}});
Ed Tanous2c70f802020-09-28 14:29:23 -07001900 count = ifaceArray.size();
Sunitha Harish462023a2020-02-19 08:34:59 -06001901 }
Sunitha Harish462023a2020-02-19 08:34:59 -06001902 },
Sunitha Harish8e651fb2020-06-17 06:06:25 -05001903 "xyz.openbmc_project.Settings",
1904 "/xyz/openbmc_project/network/hypervisor",
Sunitha Harish462023a2020-02-19 08:34:59 -06001905 "org.freedesktop.DBus.Properties", "Get",
1906 "xyz.openbmc_project.Network.SystemConfiguration", "HostName");
Ed Tanous1abe55e2018-09-05 08:30:59 -07001907 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001908};
1909
1910/**
Ed Tanouscc340dd2018-08-29 13:43:38 -07001911 * SystemActionsReset class supports handle POST method for Reset action.
1912 * The class retrieves and sends data directly to D-Bus.
1913 */
1914class SystemActionsReset : public Node
1915{
1916 public:
Ed Tanous52cc1122020-07-18 13:51:21 -07001917 SystemActionsReset(App& app) :
Ed Tanous029573d2019-02-01 10:57:49 -08001918 Node(app, "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/")
Ed Tanouscc340dd2018-08-29 13:43:38 -07001919 {
1920 entityPrivileges = {
1921 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1922 }
1923
1924 private:
1925 /**
1926 * Function handles POST method request.
1927 * Analyzes POST body message before sends Reset request data to D-Bus.
1928 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001929 void doPost(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1930 const crow::Request& req,
Ed Tanouscb13a392020-07-25 19:02:03 +00001931 const std::vector<std::string>&) override
Ed Tanouscc340dd2018-08-29 13:43:38 -07001932 {
Ed Tanous9712f8a2018-09-21 13:38:49 -07001933
1934 std::string resetType;
zhanghch058d1b46d2021-04-01 11:18:24 +08001935 if (!json_util::readJson(req, asyncResp->res, "ResetType", resetType))
Ed Tanouscc340dd2018-08-29 13:43:38 -07001936 {
1937 return;
1938 }
1939
Jason M. Billsd22c8392019-06-03 13:59:03 -07001940 // Get the command and host vs. chassis
Ed Tanous9712f8a2018-09-21 13:38:49 -07001941 std::string command;
Jason M. Billsd22c8392019-06-03 13:59:03 -07001942 bool hostCommand;
Ed Tanousd4d25792020-09-29 15:15:03 -07001943 if ((resetType == "On") || (resetType == "ForceOn"))
Ed Tanous9712f8a2018-09-21 13:38:49 -07001944 {
1945 command = "xyz.openbmc_project.State.Host.Transition.On";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001946 hostCommand = true;
1947 }
1948 else if (resetType == "ForceOff")
1949 {
1950 command = "xyz.openbmc_project.State.Chassis.Transition.Off";
1951 hostCommand = false;
1952 }
Jason M. Billsd22c8392019-06-03 13:59:03 -07001953 else if (resetType == "ForceRestart")
1954 {
Jason M. Bills86a08512020-02-04 13:15:49 -08001955 command =
1956 "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
1957 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001958 }
1959 else if (resetType == "GracefulShutdown")
1960 {
1961 command = "xyz.openbmc_project.State.Host.Transition.Off";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001962 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001963 }
1964 else if (resetType == "GracefulRestart")
1965 {
Jason M. Bills86a08512020-02-04 13:15:49 -08001966 command =
1967 "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001968 hostCommand = true;
1969 }
1970 else if (resetType == "PowerCycle")
1971 {
Jason M. Bills86a08512020-02-04 13:15:49 -08001972 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
1973 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001974 }
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001975 else if (resetType == "Nmi")
1976 {
1977 doNMI(asyncResp);
1978 return;
1979 }
Ed Tanous9712f8a2018-09-21 13:38:49 -07001980 else
1981 {
zhanghch058d1b46d2021-04-01 11:18:24 +08001982 messages::actionParameterUnknown(asyncResp->res, "Reset",
1983 resetType);
Ed Tanous9712f8a2018-09-21 13:38:49 -07001984 return;
1985 }
1986
Jason M. Billsd22c8392019-06-03 13:59:03 -07001987 if (hostCommand)
1988 {
1989 crow::connections::systemBus->async_method_call(
1990 [asyncResp, resetType](const boost::system::error_code ec) {
1991 if (ec)
1992 {
1993 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1994 if (ec.value() == boost::asio::error::invalid_argument)
1995 {
1996 messages::actionParameterNotSupported(
1997 asyncResp->res, resetType, "Reset");
1998 }
1999 else
2000 {
2001 messages::internalError(asyncResp->res);
2002 }
2003 return;
2004 }
2005 messages::success(asyncResp->res);
2006 },
2007 "xyz.openbmc_project.State.Host",
2008 "/xyz/openbmc_project/state/host0",
2009 "org.freedesktop.DBus.Properties", "Set",
2010 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
2011 std::variant<std::string>{command});
2012 }
2013 else
2014 {
2015 crow::connections::systemBus->async_method_call(
2016 [asyncResp, resetType](const boost::system::error_code ec) {
2017 if (ec)
2018 {
2019 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
2020 if (ec.value() == boost::asio::error::invalid_argument)
2021 {
2022 messages::actionParameterNotSupported(
2023 asyncResp->res, resetType, "Reset");
2024 }
2025 else
2026 {
2027 messages::internalError(asyncResp->res);
2028 }
2029 return;
2030 }
2031 messages::success(asyncResp->res);
2032 },
2033 "xyz.openbmc_project.State.Chassis",
2034 "/xyz/openbmc_project/state/chassis0",
2035 "org.freedesktop.DBus.Properties", "Set",
2036 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
2037 std::variant<std::string>{command});
2038 }
Ed Tanouscc340dd2018-08-29 13:43:38 -07002039 }
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05002040 /**
2041 * Function transceives data with dbus directly.
2042 */
zhanghch058d1b46d2021-04-01 11:18:24 +08002043 void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05002044 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -05002045 constexpr char const* serviceName =
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05002046 "xyz.openbmc_project.Control.Host.NMI";
Gunnar Mills1214b7e2020-06-04 10:11:30 -05002047 constexpr char const* objectPath =
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05002048 "/xyz/openbmc_project/control/host0/nmi";
Gunnar Mills1214b7e2020-06-04 10:11:30 -05002049 constexpr char const* interfaceName =
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05002050 "xyz.openbmc_project.Control.Host.NMI";
Gunnar Mills1214b7e2020-06-04 10:11:30 -05002051 constexpr char const* method = "NMI";
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05002052
2053 crow::connections::systemBus->async_method_call(
2054 [asyncResp](const boost::system::error_code ec) {
2055 if (ec)
2056 {
2057 BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
2058 messages::internalError(asyncResp->res);
2059 return;
2060 }
2061 messages::success(asyncResp->res);
2062 },
2063 serviceName, objectPath, interfaceName, method);
2064 }
Ed Tanouscc340dd2018-08-29 13:43:38 -07002065};
2066
2067/**
Ed Tanous66173382018-08-15 18:20:59 -07002068 * Systems derived class for delivering Computer Systems Schema.
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002069 */
Ed Tanous1abe55e2018-09-05 08:30:59 -07002070class Systems : public Node
2071{
2072 public:
2073 /*
2074 * Default Constructor
2075 */
Ed Tanous52cc1122020-07-18 13:51:21 -07002076 Systems(App& app) : Node(app, "/redfish/v1/Systems/system/")
Ed Tanous1abe55e2018-09-05 08:30:59 -07002077 {
Ed Tanous1abe55e2018-09-05 08:30:59 -07002078 entityPrivileges = {
2079 {boost::beast::http::verb::get, {{"Login"}}},
2080 {boost::beast::http::verb::head, {{"Login"}}},
2081 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
2082 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
2083 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
2084 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002085 }
2086
Ed Tanous1abe55e2018-09-05 08:30:59 -07002087 private:
Ed Tanous1abe55e2018-09-05 08:30:59 -07002088 /**
2089 * Functions triggers appropriate requests on DBus
2090 */
zhanghch058d1b46d2021-04-01 11:18:24 +08002091 void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2092 const crow::Request&, const std::vector<std::string>&) override
Ed Tanous1abe55e2018-09-05 08:30:59 -07002093 {
zhanghch058d1b46d2021-04-01 11:18:24 +08002094 asyncResp->res.jsonValue["@odata.type"] =
2095 "#ComputerSystem.v1_13_0.ComputerSystem";
2096 asyncResp->res.jsonValue["Name"] = "system";
2097 asyncResp->res.jsonValue["Id"] = "system";
2098 asyncResp->res.jsonValue["SystemType"] = "Physical";
2099 asyncResp->res.jsonValue["Description"] = "Computer System";
2100 asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
2101 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
2102 "Disabled";
2103 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
2104 uint64_t(0);
2105 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
2106 "Disabled";
2107 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
Ed Tanous04a258f2018-10-15 08:00:41 -07002108
zhanghch058d1b46d2021-04-01 11:18:24 +08002109 asyncResp->res.jsonValue["Processors"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08002110 {"@odata.id", "/redfish/v1/Systems/system/Processors"}};
zhanghch058d1b46d2021-04-01 11:18:24 +08002111 asyncResp->res.jsonValue["Memory"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08002112 {"@odata.id", "/redfish/v1/Systems/system/Memory"}};
zhanghch058d1b46d2021-04-01 11:18:24 +08002113 asyncResp->res.jsonValue["Storage"] = {
Nikhil Potadea25aecc2019-08-23 16:35:26 -07002114 {"@odata.id", "/redfish/v1/Systems/system/Storage"}};
Ed Tanous029573d2019-02-01 10:57:49 -08002115
zhanghch058d1b46d2021-04-01 11:18:24 +08002116 asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"] = {
Ed Tanouscc340dd2018-08-29 13:43:38 -07002117 {"target",
Ed Tanous029573d2019-02-01 10:57:49 -08002118 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"},
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05302119 {"@Redfish.ActionInfo",
2120 "/redfish/v1/Systems/system/ResetActionInfo"}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002121
zhanghch058d1b46d2021-04-01 11:18:24 +08002122 asyncResp->res.jsonValue["LogServices"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08002123 {"@odata.id", "/redfish/v1/Systems/system/LogServices"}};
Jason M. Billsc4bf6372018-11-05 13:48:27 -08002124
zhanghch058d1b46d2021-04-01 11:18:24 +08002125 asyncResp->res.jsonValue["Bios"] = {
Carol Wangd82a3ac2019-11-21 13:56:38 +08002126 {"@odata.id", "/redfish/v1/Systems/system/Bios"}};
2127
zhanghch058d1b46d2021-04-01 11:18:24 +08002128 asyncResp->res.jsonValue["Links"]["ManagedBy"] = {
Jennifer Leec5d03ff2019-03-08 15:42:58 -08002129 {{"@odata.id", "/redfish/v1/Managers/bmc"}}};
2130
zhanghch058d1b46d2021-04-01 11:18:24 +08002131 asyncResp->res.jsonValue["Status"] = {
Jennifer Leec5d03ff2019-03-08 15:42:58 -08002132 {"Health", "OK"},
2133 {"State", "Enabled"},
2134 };
Gunnar Mills1214b7e2020-06-04 10:11:30 -05002135 constexpr const std::array<const char*, 4> inventoryForSystems = {
James Feistb49ac872019-05-21 15:12:01 -07002136 "xyz.openbmc_project.Inventory.Item.Dimm",
James Feist2ad9c2f2019-10-29 16:26:48 -07002137 "xyz.openbmc_project.Inventory.Item.Cpu",
James Feiste284a7c2019-11-20 16:20:23 -08002138 "xyz.openbmc_project.Inventory.Item.Drive",
2139 "xyz.openbmc_project.Inventory.Item.StorageController"};
James Feistb49ac872019-05-21 15:12:01 -07002140
2141 auto health = std::make_shared<HealthPopulate>(asyncResp);
2142 crow::connections::systemBus->async_method_call(
2143 [health](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05002144 std::vector<std::string>& resp) {
James Feistb49ac872019-05-21 15:12:01 -07002145 if (ec)
2146 {
2147 // no inventory
2148 return;
2149 }
2150
2151 health->inventory = std::move(resp);
2152 },
2153 "xyz.openbmc_project.ObjectMapper",
2154 "/xyz/openbmc_project/object_mapper",
2155 "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", "/",
2156 int32_t(0), inventoryForSystems);
2157
2158 health->populate();
2159
zhanghch058d1b46d2021-04-01 11:18:24 +08002160 getMainChassisId(
2161 asyncResp, [](const std::string& chassisId,
2162 const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
2163 aRsp->res.jsonValue["Links"]["Chassis"] = {
2164 {{"@odata.id", "/redfish/v1/Chassis/" + chassisId}}};
2165 });
AppaRao Pulia3002222019-11-12 21:32:59 +05302166
Gunnar Mills9f8bfa72020-09-28 13:45:19 -05002167 getLocationIndicatorActive(asyncResp);
2168 // TODO (Gunnar): Remove IndicatorLED after enough time has passed
AppaRao Pulia3002222019-11-12 21:32:59 +05302169 getIndicatorLedState(asyncResp);
James Feist5bc2dc82019-10-22 14:33:16 -07002170 getComputerSystem(asyncResp, health);
Ed Tanous6c34de42018-08-29 13:37:36 -07002171 getHostState(asyncResp);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05302172 getBootProperties(asyncResp);
Andrew Geissler978b8802020-11-19 13:36:40 -06002173 getBootProgress(asyncResp);
Jason M. Billsadbe1922019-10-14 15:44:35 -07002174 getPCIeDeviceList(asyncResp, "PCIeDevices");
Yong Li51709ff2019-09-30 14:13:04 +08002175 getHostWatchdogTimer(asyncResp);
George Liuc6a620f2020-04-10 17:18:11 +08002176 getPowerRestorePolicy(asyncResp);
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05002177 getAutomaticRetry(asyncResp);
Gunnar Millsc0557e12020-06-30 11:26:20 -05002178 getLastResetTime(asyncResp);
AppaRao Pulia6349912019-10-18 17:16:08 +05302179#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
2180 getProvisioningStatus(asyncResp);
2181#endif
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002182 }
2183
zhanghch058d1b46d2021-04-01 11:18:24 +08002184 void doPatch(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2185 const crow::Request& req,
Ed Tanouscb13a392020-07-25 19:02:03 +00002186 const std::vector<std::string>&) override
Ed Tanous1abe55e2018-09-05 08:30:59 -07002187 {
Gunnar Mills9f8bfa72020-09-28 13:45:19 -05002188 std::optional<bool> locationIndicatorActive;
Santosh Puranikcde19e52019-02-20 00:10:56 +05302189 std::optional<std::string> indicatorLed;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05302190 std::optional<nlohmann::json> bootProps;
Yong Lic45f0082019-10-10 14:19:01 +08002191 std::optional<nlohmann::json> wdtTimerProps;
Gunnar Mills98e386e2020-10-30 14:58:09 -05002192 std::optional<std::string> assetTag;
George Liuc6a620f2020-04-10 17:18:11 +08002193 std::optional<std::string> powerRestorePolicy;
Santosh Puranik41352c22019-07-03 05:35:49 -05002194
Gunnar Mills9f8bfa72020-09-28 13:45:19 -05002195 if (!json_util::readJson(
zhanghch058d1b46d2021-04-01 11:18:24 +08002196 req, asyncResp->res, "IndicatorLED", indicatorLed,
Gunnar Mills9f8bfa72020-09-28 13:45:19 -05002197 "LocationIndicatorActive", locationIndicatorActive, "Boot",
2198 bootProps, "WatchdogTimer", wdtTimerProps, "PowerRestorePolicy",
2199 powerRestorePolicy, "AssetTag", assetTag))
Ed Tanous66173382018-08-15 18:20:59 -07002200 {
Ed Tanous9712f8a2018-09-21 13:38:49 -07002201 return;
2202 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05302203
zhanghch058d1b46d2021-04-01 11:18:24 +08002204 asyncResp->res.result(boost::beast::http::status::no_content);
Yong Lic45f0082019-10-10 14:19:01 +08002205
Gunnar Mills98e386e2020-10-30 14:58:09 -05002206 if (assetTag)
2207 {
2208 setAssetTag(asyncResp, *assetTag);
2209 }
2210
Yong Lic45f0082019-10-10 14:19:01 +08002211 if (wdtTimerProps)
2212 {
2213 std::optional<bool> wdtEnable;
2214 std::optional<std::string> wdtTimeOutAction;
2215
2216 if (!json_util::readJson(*wdtTimerProps, asyncResp->res,
2217 "FunctionEnabled", wdtEnable,
2218 "TimeoutAction", wdtTimeOutAction))
2219 {
2220 return;
2221 }
Ed Tanousf23b7292020-10-15 09:41:17 -07002222 setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
Yong Lic45f0082019-10-10 14:19:01 +08002223 }
2224
Santosh Puranik491d8ee2019-02-06 19:46:56 +05302225 if (bootProps)
2226 {
2227 std::optional<std::string> bootSource;
2228 std::optional<std::string> bootEnable;
Gunnar Mills69f35302020-05-17 16:06:31 -05002229 std::optional<std::string> automaticRetryConfig;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05302230
Gunnar Mills69f35302020-05-17 16:06:31 -05002231 if (!json_util::readJson(
2232 *bootProps, asyncResp->res, "BootSourceOverrideTarget",
2233 bootSource, "BootSourceOverrideEnabled", bootEnable,
2234 "AutomaticRetryConfig", automaticRetryConfig))
Santosh Puranik491d8ee2019-02-06 19:46:56 +05302235 {
2236 return;
2237 }
Gunnar Mills69f35302020-05-17 16:06:31 -05002238 if (bootSource || bootEnable)
2239 {
2240 setBootSourceProperties(asyncResp, std::move(bootSource),
2241 std::move(bootEnable));
2242 }
2243 if (automaticRetryConfig)
2244 {
Ed Tanousf23b7292020-10-15 09:41:17 -07002245 setAutomaticRetry(asyncResp, *automaticRetryConfig);
Gunnar Mills69f35302020-05-17 16:06:31 -05002246 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05302247 }
Johnathan Mantey265c1602019-08-08 11:02:51 -07002248
Gunnar Mills9f8bfa72020-09-28 13:45:19 -05002249 if (locationIndicatorActive)
2250 {
2251 setLocationIndicatorActive(asyncResp, *locationIndicatorActive);
2252 }
2253
2254 // TODO (Gunnar): Remove IndicatorLED after enough time has passed
Ed Tanous9712f8a2018-09-21 13:38:49 -07002255 if (indicatorLed)
2256 {
Ed Tanousf23b7292020-10-15 09:41:17 -07002257 setIndicatorLedState(asyncResp, *indicatorLed);
zhanghch058d1b46d2021-04-01 11:18:24 +08002258 asyncResp->res.addHeader(boost::beast::http::field::warning,
2259 "299 - \"IndicatorLED is deprecated. Use "
2260 "LocationIndicatorActive instead.\"");
Ed Tanous1abe55e2018-09-05 08:30:59 -07002261 }
George Liuc6a620f2020-04-10 17:18:11 +08002262
2263 if (powerRestorePolicy)
2264 {
Gunnar Mills4e69c902021-01-05 19:50:11 -06002265 setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
George Liuc6a620f2020-04-10 17:18:11 +08002266 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002267 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002268};
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05302269
2270/**
2271 * SystemResetActionInfo derived class for delivering Computer Systems
2272 * ResetType AllowableValues using ResetInfo schema.
2273 */
2274class SystemResetActionInfo : public Node
2275{
2276 public:
2277 /*
2278 * Default Constructor
2279 */
Ed Tanous52cc1122020-07-18 13:51:21 -07002280 SystemResetActionInfo(App& app) :
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05302281 Node(app, "/redfish/v1/Systems/system/ResetActionInfo/")
2282 {
2283 entityPrivileges = {
2284 {boost::beast::http::verb::get, {{"Login"}}},
2285 {boost::beast::http::verb::head, {{"Login"}}},
2286 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
2287 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
2288 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
2289 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
2290 }
2291
2292 private:
2293 /**
2294 * Functions triggers appropriate requests on DBus
2295 */
zhanghch058d1b46d2021-04-01 11:18:24 +08002296 void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2297 const crow::Request&, const std::vector<std::string>&) override
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05302298 {
zhanghch058d1b46d2021-04-01 11:18:24 +08002299 asyncResp->res.jsonValue = {
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05302300 {"@odata.type", "#ActionInfo.v1_1_2.ActionInfo"},
2301 {"@odata.id", "/redfish/v1/Systems/system/ResetActionInfo"},
2302 {"Name", "Reset Action Info"},
2303 {"Id", "ResetActionInfo"},
2304 {"Parameters",
2305 {{{"Name", "ResetType"},
2306 {"Required", true},
2307 {"DataType", "String"},
2308 {"AllowableValues",
2309 {"On", "ForceOff", "ForceOn", "ForceRestart", "GracefulRestart",
2310 "GracefulShutdown", "PowerCycle", "Nmi"}}}}}};
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05302311 }
2312};
Ed Tanous1abe55e2018-09-05 08:30:59 -07002313} // namespace redfish