blob: 9220279ac7f3776714e7f03d6f23b246df583211 [file] [log] [blame]
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001/*
2// Copyright (c) 2018 Intel Corporation
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15*/
16#pragma once
17
James Feistb49ac872019-05-21 15:12:01 -070018#include "health.hpp"
James Feist1c8fba92019-12-20 15:12:07 -080019#include "led.hpp"
Jason M. Billsf5c9f8b2018-12-18 16:51:18 -080020#include "pcie.hpp"
Jennifer Leec5d03ff2019-03-08 15:42:58 -080021#include "redfish_util.hpp"
22
Ed Tanous9712f8a2018-09-21 13:38:49 -070023#include <boost/container/flat_map.hpp>
24#include <node.hpp>
Andrew Geisslercb7e1e72019-02-19 13:05:38 -060025#include <utils/fw_utils.hpp>
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020026#include <utils/json_utils.hpp>
Gunnar Mills1214b7e2020-06-04 10:11:30 -050027
Ed Tanousabf2add2019-01-22 16:40:12 -080028#include <variant>
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020029
Ed Tanous1abe55e2018-09-05 08:30:59 -070030namespace redfish
31{
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020032
Alpana Kumari9d3ae102019-04-12 06:49:32 -050033/**
34 * @brief Updates the Functional State of DIMMs
35 *
36 * @param[in] aResp Shared pointer for completing asynchronous calls
37 * @param[in] dimmState Dimm's Functional state, true/false
38 *
39 * @return None.
40 */
Ed Tanous23a21a12020-07-25 04:45:05 +000041inline void updateDimmProperties(std::shared_ptr<AsyncResp> aResp,
42 const std::variant<bool>& dimmState)
Alpana Kumari9d3ae102019-04-12 06:49:32 -050043{
Gunnar Mills1214b7e2020-06-04 10:11:30 -050044 const bool* isDimmFunctional = std::get_if<bool>(&dimmState);
Alpana Kumari9d3ae102019-04-12 06:49:32 -050045 if (isDimmFunctional == nullptr)
46 {
47 messages::internalError(aResp->res);
48 return;
49 }
Gunnar Mills698654b2019-10-16 13:17:37 -050050 BMCWEB_LOG_DEBUG << "Dimm Functional: " << *isDimmFunctional;
Alpana Kumari9d3ae102019-04-12 06:49:32 -050051
Gunnar Mills4e0453b2020-07-08 14:00:30 -050052 // Set it as Enabled if at least one DIMM is functional
Alpana Kumari9d3ae102019-04-12 06:49:32 -050053 // Update STATE only if previous State was DISABLED and current Dimm is
54 // ENABLED.
Gunnar Mills1214b7e2020-06-04 10:11:30 -050055 nlohmann::json& prevMemSummary =
Alpana Kumari9d3ae102019-04-12 06:49:32 -050056 aResp->res.jsonValue["MemorySummary"]["Status"]["State"];
57 if (prevMemSummary == "Disabled")
58 {
59 if (*isDimmFunctional == true)
60 {
61 aResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
62 "Enabled";
63 }
64 }
65}
66
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050067/*
68 * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState
69 *
70 * @param[in] aResp Shared pointer for completing asynchronous calls
71 * @param[in] cpuPresenceState CPU present or not
72 *
73 * @return None.
74 */
Ed Tanous23a21a12020-07-25 04:45:05 +000075inline void modifyCpuPresenceState(std::shared_ptr<AsyncResp> aResp,
76 const std::variant<bool>& cpuPresenceState)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050077{
Gunnar Mills1214b7e2020-06-04 10:11:30 -050078 const bool* isCpuPresent = std::get_if<bool>(&cpuPresenceState);
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050079
80 if (isCpuPresent == nullptr)
81 {
82 messages::internalError(aResp->res);
83 return;
84 }
Gunnar Mills698654b2019-10-16 13:17:37 -050085 BMCWEB_LOG_DEBUG << "Cpu Present: " << *isCpuPresent;
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050086
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050087 if (*isCpuPresent == true)
88 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -050089 nlohmann::json& procCount =
James Feistb4b95952019-12-05 15:01:55 -080090 aResp->res.jsonValue["ProcessorSummary"]["Count"];
91 auto procCountPtr =
Gunnar Mills1214b7e2020-06-04 10:11:30 -050092 procCount.get_ptr<nlohmann::json::number_integer_t*>();
James Feistb4b95952019-12-05 15:01:55 -080093 if (procCountPtr != nullptr)
94 {
95 // shouldn't be possible to be nullptr
96 *procCountPtr += 1;
97 }
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050098 }
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050099}
100
101/*
102 * @brief Update "ProcessorSummary" "Status" "State" based on
103 * CPU Functional State
104 *
105 * @param[in] aResp Shared pointer for completing asynchronous calls
106 * @param[in] cpuFunctionalState is CPU functional true/false
107 *
108 * @return None.
109 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000110inline void
111 modifyCpuFunctionalState(std::shared_ptr<AsyncResp> aResp,
112 const std::variant<bool>& cpuFunctionalState)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500113{
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500114 const bool* isCpuFunctional = std::get_if<bool>(&cpuFunctionalState);
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500115
116 if (isCpuFunctional == nullptr)
117 {
118 messages::internalError(aResp->res);
119 return;
120 }
Gunnar Mills698654b2019-10-16 13:17:37 -0500121 BMCWEB_LOG_DEBUG << "Cpu Functional: " << *isCpuFunctional;
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500122
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500123 nlohmann::json& prevProcState =
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500124 aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"];
125
Gunnar Mills4e0453b2020-07-08 14:00:30 -0500126 // Set it as Enabled if at least one CPU is functional
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500127 // Update STATE only if previous State was Non_Functional and current CPU is
128 // Functional.
129 if (prevProcState == "Disabled")
130 {
131 if (*isCpuFunctional == true)
132 {
133 aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
134 "Enabled";
135 }
136 }
137}
138
139/*
Ed Tanous6c34de42018-08-29 13:37:36 -0700140 * @brief Retrieves computer system properties over dbus
141 *
142 * @param[in] aResp Shared pointer for completing asynchronous calls
143 * @param[in] name Computer system name from request
144 *
145 * @return None.
146 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000147inline void getComputerSystem(std::shared_ptr<AsyncResp> aResp,
148 std::shared_ptr<HealthPopulate> systemHealth)
Ed Tanous6c34de42018-08-29 13:37:36 -0700149{
Ed Tanous6c34de42018-08-29 13:37:36 -0700150 BMCWEB_LOG_DEBUG << "Get available system components.";
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500151
Ed Tanous6c34de42018-08-29 13:37:36 -0700152 crow::connections::systemBus->async_method_call(
James Feist5bc2dc82019-10-22 14:33:16 -0700153 [aResp, systemHealth](
Ed Tanous6c34de42018-08-29 13:37:36 -0700154 const boost::system::error_code ec,
155 const std::vector<std::pair<
156 std::string,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500157 std::vector<std::pair<std::string, std::vector<std::string>>>>>&
158 subtree) {
Ed Tanous6c34de42018-08-29 13:37:36 -0700159 if (ec)
160 {
161 BMCWEB_LOG_DEBUG << "DBUS response error";
Jason M. Billsf12894f2018-10-09 12:45:45 -0700162 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700163 return;
164 }
Ed Tanous6c34de42018-08-29 13:37:36 -0700165 // Iterate over all retrieved ObjectPaths.
166 for (const std::pair<std::string,
167 std::vector<std::pair<
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500168 std::string, std::vector<std::string>>>>&
169 object : subtree)
Ed Tanous6c34de42018-08-29 13:37:36 -0700170 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500171 const std::string& path = object.first;
Ed Tanous6c34de42018-08-29 13:37:36 -0700172 BMCWEB_LOG_DEBUG << "Got path: " << path;
173 const std::vector<
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500174 std::pair<std::string, std::vector<std::string>>>&
175 connectionNames = object.second;
Ed Tanous6c34de42018-08-29 13:37:36 -0700176 if (connectionNames.size() < 1)
177 {
178 continue;
179 }
Ed Tanous029573d2019-02-01 10:57:49 -0800180
James Feist5bc2dc82019-10-22 14:33:16 -0700181 auto memoryHealth = std::make_shared<HealthPopulate>(
182 aResp, aResp->res.jsonValue["MemorySummary"]["Status"]);
183
184 auto cpuHealth = std::make_shared<HealthPopulate>(
185 aResp, aResp->res.jsonValue["ProcessorSummary"]["Status"]);
186
187 systemHealth->children.emplace_back(memoryHealth);
188 systemHealth->children.emplace_back(cpuHealth);
189
Ed Tanous029573d2019-02-01 10:57:49 -0800190 // This is not system, so check if it's cpu, dimm, UUID or
191 // BiosVer
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500192 for (const auto& connection : connectionNames)
Ed Tanous6c34de42018-08-29 13:37:36 -0700193 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500194 for (const auto& interfaceName : connection.second)
Ed Tanous6c34de42018-08-29 13:37:36 -0700195 {
Ed Tanous029573d2019-02-01 10:57:49 -0800196 if (interfaceName ==
197 "xyz.openbmc_project.Inventory.Item.Dimm")
Ed Tanous6c34de42018-08-29 13:37:36 -0700198 {
Ed Tanous029573d2019-02-01 10:57:49 -0800199 BMCWEB_LOG_DEBUG
200 << "Found Dimm, now get its properties.";
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500201
Ed Tanous029573d2019-02-01 10:57:49 -0800202 crow::connections::systemBus->async_method_call(
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500203 [aResp, service{connection.first},
204 path(std::move(path))](
Ed Tanouscb13a392020-07-25 19:02:03 +0000205 const boost::system::error_code ec2,
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500206 const std::vector<
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500207 std::pair<std::string, VariantType>>&
208 properties) {
Ed Tanouscb13a392020-07-25 19:02:03 +0000209 if (ec2)
Ed Tanous029573d2019-02-01 10:57:49 -0800210 {
211 BMCWEB_LOG_ERROR
Ed Tanouscb13a392020-07-25 19:02:03 +0000212 << "DBUS response error " << ec2;
Ed Tanous029573d2019-02-01 10:57:49 -0800213 messages::internalError(aResp->res);
214 return;
215 }
216 BMCWEB_LOG_DEBUG << "Got "
217 << properties.size()
Gunnar Mills698654b2019-10-16 13:17:37 -0500218 << " Dimm properties.";
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500219
220 if (properties.size() > 0)
Ed Tanous029573d2019-02-01 10:57:49 -0800221 {
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500222 for (const std::pair<std::string,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500223 VariantType>&
224 property : properties)
Ed Tanous6c34de42018-08-29 13:37:36 -0700225 {
Cheng C Yang5fd7ba62019-11-28 15:58:08 +0800226 if (property.first !=
227 "MemorySizeInKB")
Ed Tanous6c34de42018-08-29 13:37:36 -0700228 {
Cheng C Yang5fd7ba62019-11-28 15:58:08 +0800229 continue;
Ed Tanous6c34de42018-08-29 13:37:36 -0700230 }
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500231 const uint32_t* value =
Patrick Williams8d78b7a2020-05-13 11:24:20 -0500232 std::get_if<uint32_t>(
233 &property.second);
Cheng C Yang5fd7ba62019-11-28 15:58:08 +0800234 if (value == nullptr)
235 {
236 BMCWEB_LOG_DEBUG
237 << "Find incorrect type of "
238 "MemorySize";
239 continue;
240 }
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500241 nlohmann::json& totalMemory =
Cheng C Yang5fd7ba62019-11-28 15:58:08 +0800242 aResp->res
243 .jsonValue["MemorySummar"
244 "y"]
245 ["TotalSystemMe"
246 "moryGiB"];
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500247 uint64_t* preValue =
Cheng C Yang5fd7ba62019-11-28 15:58:08 +0800248 totalMemory
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500249 .get_ptr<uint64_t*>();
Cheng C Yang5fd7ba62019-11-28 15:58:08 +0800250 if (preValue == nullptr)
251 {
252 continue;
253 }
254 aResp->res
255 .jsonValue["MemorySummary"]
256 ["TotalSystemMemoryGi"
257 "B"] =
258 *value / (1024 * 1024) +
259 *preValue;
260 aResp->res
261 .jsonValue["MemorySummary"]
262 ["Status"]["State"] =
263 "Enabled";
Ed Tanous6c34de42018-08-29 13:37:36 -0700264 }
Ed Tanous029573d2019-02-01 10:57:49 -0800265 }
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500266 else
267 {
268 auto getDimmProperties =
269 [aResp](
270 const boost::system::error_code
Ed Tanouscb13a392020-07-25 19:02:03 +0000271 ec3,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500272 const std::variant<bool>&
273 dimmState) {
Ed Tanouscb13a392020-07-25 19:02:03 +0000274 if (ec3)
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500275 {
276 BMCWEB_LOG_ERROR
277 << "DBUS response "
278 "error "
Ed Tanouscb13a392020-07-25 19:02:03 +0000279 << ec3;
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500280 return;
281 }
282 updateDimmProperties(aResp,
283 dimmState);
284 };
285 crow::connections::systemBus
286 ->async_method_call(
287 std::move(getDimmProperties),
288 service, path,
289 "org.freedesktop.DBus."
290 "Properties",
291 "Get",
292 "xyz.openbmc_project.State."
293 "Decorator.OperationalStatus",
294 "Functional");
295 }
Ed Tanous029573d2019-02-01 10:57:49 -0800296 },
297 connection.first, path,
298 "org.freedesktop.DBus.Properties", "GetAll",
299 "xyz.openbmc_project.Inventory.Item.Dimm");
James Feist5bc2dc82019-10-22 14:33:16 -0700300
301 memoryHealth->inventory.emplace_back(path);
Ed Tanous029573d2019-02-01 10:57:49 -0800302 }
303 else if (interfaceName ==
304 "xyz.openbmc_project.Inventory.Item.Cpu")
305 {
306 BMCWEB_LOG_DEBUG
307 << "Found Cpu, now get its properties.";
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500308
Ed Tanous029573d2019-02-01 10:57:49 -0800309 crow::connections::systemBus->async_method_call(
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500310 [aResp, service{connection.first},
311 path(std::move(path))](
Ed Tanouscb13a392020-07-25 19:02:03 +0000312 const boost::system::error_code ec2,
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500313 const std::vector<
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500314 std::pair<std::string, VariantType>>&
315 properties) {
Ed Tanouscb13a392020-07-25 19:02:03 +0000316 if (ec2)
Ed Tanous029573d2019-02-01 10:57:49 -0800317 {
318 BMCWEB_LOG_ERROR
Ed Tanouscb13a392020-07-25 19:02:03 +0000319 << "DBUS response error " << ec2;
Ed Tanous029573d2019-02-01 10:57:49 -0800320 messages::internalError(aResp->res);
321 return;
322 }
323 BMCWEB_LOG_DEBUG << "Got "
324 << properties.size()
Gunnar Mills698654b2019-10-16 13:17:37 -0500325 << " Cpu properties.";
Ed Tanous04a258f2018-10-15 08:00:41 -0700326
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500327 if (properties.size() > 0)
328 {
Zhikui Ren9cf21522020-09-10 11:13:14 -0700329 const uint64_t* processorId = nullptr;
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700330 const std::string* procFamily = nullptr;
331 nlohmann::json& procSummary =
332 aResp->res.jsonValue["ProcessorSumm"
333 "ary"];
334 nlohmann::json& procCount =
335 procSummary["Count"];
336
337 auto procCountPtr = procCount.get_ptr<
338 nlohmann::json::
339 number_integer_t*>();
340 if (procCountPtr == nullptr)
341 {
342 messages::internalError(aResp->res);
343 return;
344 }
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500345 for (const auto& property : properties)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500346 {
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700347
Zhikui Ren9cf21522020-09-10 11:13:14 -0700348 if (property.first == "Id")
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700349 {
350 processorId =
Zhikui Ren9cf21522020-09-10 11:13:14 -0700351 std::get_if<uint64_t>(
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700352 &property.second);
353 if (nullptr != procFamily)
354 break;
355 continue;
356 }
357
Zhikui Ren9cf21522020-09-10 11:13:14 -0700358 if (property.first == "Family")
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500359 {
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700360 procFamily =
Patrick Williams8d78b7a2020-05-13 11:24:20 -0500361 std::get_if<std::string>(
362 &property.second);
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700363 if (nullptr != processorId)
364 break;
365 continue;
366 }
367 }
James Feistb4b95952019-12-05 15:01:55 -0800368
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700369 if (procFamily != nullptr &&
370 processorId != nullptr)
371 {
372 if (procCountPtr != nullptr &&
373 *processorId != 0)
374 {
375 *procCountPtr += 1;
376 procSummary["Status"]["State"] =
377 "Enabled";
378
379 procSummary["Model"] =
380 *procFamily;
Ed Tanous6c34de42018-08-29 13:37:36 -0700381 }
382 }
Ed Tanous029573d2019-02-01 10:57:49 -0800383 }
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500384 else
385 {
386 auto getCpuPresenceState =
387 [aResp](
388 const boost::system::error_code
Ed Tanouscb13a392020-07-25 19:02:03 +0000389 ec3,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500390 const std::variant<bool>&
391 cpuPresenceCheck) {
Ed Tanouscb13a392020-07-25 19:02:03 +0000392 if (ec3)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500393 {
394 BMCWEB_LOG_ERROR
395 << "DBUS response "
396 "error "
Ed Tanouscb13a392020-07-25 19:02:03 +0000397 << ec3;
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500398 return;
399 }
400 modifyCpuPresenceState(
401 aResp, cpuPresenceCheck);
402 };
403
404 auto getCpuFunctionalState =
405 [aResp](
406 const boost::system::error_code
Ed Tanouscb13a392020-07-25 19:02:03 +0000407 ec3,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500408 const std::variant<bool>&
409 cpuFunctionalCheck) {
Ed Tanouscb13a392020-07-25 19:02:03 +0000410 if (ec3)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500411 {
412 BMCWEB_LOG_ERROR
413 << "DBUS response "
414 "error "
Ed Tanouscb13a392020-07-25 19:02:03 +0000415 << ec3;
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500416 return;
417 }
418 modifyCpuFunctionalState(
419 aResp, cpuFunctionalCheck);
420 };
421 // Get the Presence of CPU
422 crow::connections::systemBus
423 ->async_method_call(
424 std::move(getCpuPresenceState),
425 service, path,
426 "org.freedesktop.DBus."
427 "Properties",
428 "Get",
429 "xyz.openbmc_project.Inventory."
430 "Item",
431 "Present");
432
433 // Get the Functional State
434 crow::connections::systemBus
435 ->async_method_call(
436 std::move(
437 getCpuFunctionalState),
438 service, path,
439 "org.freedesktop.DBus."
440 "Properties",
441 "Get",
442 "xyz.openbmc_project.State."
443 "Decorator."
444 "OperationalStatus",
445 "Functional");
446
447 // Get the MODEL from
448 // xyz.openbmc_project.Inventory.Decorator.Asset
449 // support it later as Model is Empty
450 // currently.
451 }
Ed Tanous029573d2019-02-01 10:57:49 -0800452 },
453 connection.first, path,
454 "org.freedesktop.DBus.Properties", "GetAll",
455 "xyz.openbmc_project.Inventory.Item.Cpu");
James Feist5bc2dc82019-10-22 14:33:16 -0700456
457 cpuHealth->inventory.emplace_back(path);
Ed Tanous029573d2019-02-01 10:57:49 -0800458 }
459 else if (interfaceName ==
460 "xyz.openbmc_project.Common.UUID")
461 {
462 BMCWEB_LOG_DEBUG
463 << "Found UUID, now get its properties.";
464 crow::connections::systemBus->async_method_call(
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500465 [aResp](
Ed Tanouscb13a392020-07-25 19:02:03 +0000466 const boost::system::error_code ec3,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500467 const std::vector<
468 std::pair<std::string, VariantType>>&
469 properties) {
Ed Tanouscb13a392020-07-25 19:02:03 +0000470 if (ec3)
Ed Tanous029573d2019-02-01 10:57:49 -0800471 {
472 BMCWEB_LOG_DEBUG
Ed Tanouscb13a392020-07-25 19:02:03 +0000473 << "DBUS response error " << ec3;
Ed Tanous029573d2019-02-01 10:57:49 -0800474 messages::internalError(aResp->res);
475 return;
476 }
477 BMCWEB_LOG_DEBUG << "Got "
478 << properties.size()
Gunnar Mills698654b2019-10-16 13:17:37 -0500479 << " UUID properties.";
Ed Tanous029573d2019-02-01 10:57:49 -0800480 for (const std::pair<std::string,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500481 VariantType>&
482 property : properties)
Ed Tanous029573d2019-02-01 10:57:49 -0800483 {
Ed Tanous029573d2019-02-01 10:57:49 -0800484 if (property.first == "UUID")
485 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500486 const std::string* value =
Patrick Williams8d78b7a2020-05-13 11:24:20 -0500487 std::get_if<std::string>(
488 &property.second);
Ed Tanous04a258f2018-10-15 08:00:41 -0700489
Ed Tanous029573d2019-02-01 10:57:49 -0800490 if (value != nullptr)
491 {
492 std::string valueStr = *value;
493 if (valueStr.size() == 32)
Ed Tanous6c34de42018-08-29 13:37:36 -0700494 {
Ed Tanous029573d2019-02-01 10:57:49 -0800495 valueStr.insert(8, 1, '-');
496 valueStr.insert(13, 1, '-');
497 valueStr.insert(18, 1, '-');
498 valueStr.insert(23, 1, '-');
Ed Tanous6c34de42018-08-29 13:37:36 -0700499 }
Ed Tanous029573d2019-02-01 10:57:49 -0800500 BMCWEB_LOG_DEBUG << "UUID = "
501 << valueStr;
502 aResp->res.jsonValue["UUID"] =
503 valueStr;
Ed Tanous6c34de42018-08-29 13:37:36 -0700504 }
505 }
Ed Tanous029573d2019-02-01 10:57:49 -0800506 }
507 },
508 connection.first, path,
509 "org.freedesktop.DBus.Properties", "GetAll",
510 "xyz.openbmc_project.Common.UUID");
511 }
512 else if (interfaceName ==
513 "xyz.openbmc_project.Inventory.Item.System")
514 {
515 crow::connections::systemBus->async_method_call(
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500516 [aResp](
Ed Tanouscb13a392020-07-25 19:02:03 +0000517 const boost::system::error_code ec2,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500518 const std::vector<
519 std::pair<std::string, VariantType>>&
520 propertiesList) {
Ed Tanouscb13a392020-07-25 19:02:03 +0000521 if (ec2)
Ed Tanous029573d2019-02-01 10:57:49 -0800522 {
James Feiste4a4b9a2019-06-20 14:08:07 -0700523 // doesn't have to include this
524 // interface
Ed Tanous029573d2019-02-01 10:57:49 -0800525 return;
526 }
Gunnar Mills698654b2019-10-16 13:17:37 -0500527 BMCWEB_LOG_DEBUG
528 << "Got " << propertiesList.size()
529 << " properties for system";
Ed Tanous029573d2019-02-01 10:57:49 -0800530 for (const std::pair<std::string,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500531 VariantType>&
532 property : propertiesList)
Ed Tanous029573d2019-02-01 10:57:49 -0800533 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500534 const std::string& propertyName =
beccabroekfc5afcf2019-03-05 14:35:15 -0600535 property.first;
536 if ((propertyName == "PartNumber") ||
537 (propertyName == "SerialNumber") ||
538 (propertyName == "Manufacturer") ||
539 (propertyName == "Model"))
Ed Tanous029573d2019-02-01 10:57:49 -0800540 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500541 const std::string* value =
beccabroekfc5afcf2019-03-05 14:35:15 -0600542 std::get_if<std::string>(
543 &property.second);
544 if (value != nullptr)
545 {
546 aResp->res
547 .jsonValue[propertyName] =
548 *value;
549 }
Ed Tanous029573d2019-02-01 10:57:49 -0800550 }
551 }
Gunnar Millsc1e236a2020-04-14 21:36:33 -0500552
Andrew Geisslercb7e1e72019-02-19 13:05:38 -0600553 // Grab the bios version
Gunnar Millsf97ddba2020-08-20 15:57:40 -0500554 fw_util::populateFirmwareInformation(
Andrew Geisslercb7e1e72019-02-19 13:05:38 -0600555 aResp, fw_util::biosPurpose,
Gunnar Mills72d566d2020-07-21 12:44:00 -0500556 "BiosVersion", false);
Ed Tanous029573d2019-02-01 10:57:49 -0800557 },
558 connection.first, path,
559 "org.freedesktop.DBus.Properties", "GetAll",
560 "xyz.openbmc_project.Inventory.Decorator."
561 "Asset");
James Feiste4a4b9a2019-06-20 14:08:07 -0700562
563 crow::connections::systemBus->async_method_call(
564 [aResp](
Ed Tanouscb13a392020-07-25 19:02:03 +0000565 const boost::system::error_code ec2,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500566 const std::variant<std::string>& property) {
Ed Tanouscb13a392020-07-25 19:02:03 +0000567 if (ec2)
James Feiste4a4b9a2019-06-20 14:08:07 -0700568 {
569 // doesn't have to include this
570 // interface
571 return;
572 }
573
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500574 const std::string* value =
James Feiste4a4b9a2019-06-20 14:08:07 -0700575 std::get_if<std::string>(&property);
576 if (value != nullptr)
577 {
578 aResp->res.jsonValue["AssetTag"] =
579 *value;
580 }
581 },
582 connection.first, path,
583 "org.freedesktop.DBus.Properties", "Get",
584 "xyz.openbmc_project.Inventory.Decorator."
585 "AssetTag",
586 "AssetTag");
Ed Tanous6c34de42018-08-29 13:37:36 -0700587 }
588 }
589 }
590 }
Ed Tanous6c34de42018-08-29 13:37:36 -0700591 },
592 "xyz.openbmc_project.ObjectMapper",
593 "/xyz/openbmc_project/object_mapper",
594 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
Ed Tanous66173382018-08-15 18:20:59 -0700595 "/xyz/openbmc_project/inventory", int32_t(0),
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500596 std::array<const char*, 5>{
Ed Tanous66173382018-08-15 18:20:59 -0700597 "xyz.openbmc_project.Inventory.Decorator.Asset",
598 "xyz.openbmc_project.Inventory.Item.Cpu",
599 "xyz.openbmc_project.Inventory.Item.Dimm",
600 "xyz.openbmc_project.Inventory.Item.System",
601 "xyz.openbmc_project.Common.UUID",
602 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700603}
604
605/**
Ed Tanous6c34de42018-08-29 13:37:36 -0700606 * @brief Retrieves host state properties over dbus
607 *
608 * @param[in] aResp Shared pointer for completing asynchronous calls.
609 *
610 * @return None.
611 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000612inline void getHostState(std::shared_ptr<AsyncResp> aResp)
Ed Tanous6c34de42018-08-29 13:37:36 -0700613{
614 BMCWEB_LOG_DEBUG << "Get host information.";
615 crow::connections::systemBus->async_method_call(
Jennifer Leec5d03ff2019-03-08 15:42:58 -0800616 [aResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500617 const std::variant<std::string>& hostState) {
Ed Tanous6c34de42018-08-29 13:37:36 -0700618 if (ec)
619 {
620 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700621 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700622 return;
623 }
Ed Tanous66173382018-08-15 18:20:59 -0700624
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500625 const std::string* s = std::get_if<std::string>(&hostState);
Ed Tanous66173382018-08-15 18:20:59 -0700626 BMCWEB_LOG_DEBUG << "Host state: " << *s;
627 if (s != nullptr)
Ed Tanous6c34de42018-08-29 13:37:36 -0700628 {
Ed Tanous66173382018-08-15 18:20:59 -0700629 // Verify Host State
Andrew Geissler94732662019-01-08 19:32:16 -0800630 if (*s == "xyz.openbmc_project.State.Host.HostState.Running")
Ed Tanous6c34de42018-08-29 13:37:36 -0700631 {
Ed Tanous66173382018-08-15 18:20:59 -0700632 aResp->res.jsonValue["PowerState"] = "On";
633 aResp->res.jsonValue["Status"]["State"] = "Enabled";
634 }
Andrew Geissler83935af2020-02-13 10:24:53 -0600635 else if (*s == "xyz.openbmc_project.State.Host.HostState."
Gunnar Mills8c888602020-05-01 14:25:09 -0500636 "Quiesced")
637 {
638 aResp->res.jsonValue["PowerState"] = "On";
639 aResp->res.jsonValue["Status"]["State"] = "Quiesced";
640 }
641 else if (*s == "xyz.openbmc_project.State.Host.HostState."
Andrew Geissler83935af2020-02-13 10:24:53 -0600642 "DiagnosticMode")
643 {
644 aResp->res.jsonValue["PowerState"] = "On";
645 aResp->res.jsonValue["Status"]["State"] = "InTest";
646 }
Ed Tanous66173382018-08-15 18:20:59 -0700647 else
648 {
649 aResp->res.jsonValue["PowerState"] = "Off";
650 aResp->res.jsonValue["Status"]["State"] = "Disabled";
Ed Tanous6c34de42018-08-29 13:37:36 -0700651 }
652 }
653 },
654 "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
Ed Tanous66173382018-08-15 18:20:59 -0700655 "org.freedesktop.DBus.Properties", "Get",
656 "xyz.openbmc_project.State.Host", "CurrentHostState");
Ed Tanous6c34de42018-08-29 13:37:36 -0700657}
658
659/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500660 * @brief Translates boot source DBUS property value to redfish.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530661 *
662 * @param[in] dbusSource The boot source in DBUS speak.
663 *
664 * @return Returns as a string, the boot source in Redfish terms. If translation
665 * cannot be done, returns an empty string.
666 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000667inline std::string dbusToRfBootSource(const std::string& dbusSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530668{
669 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
670 {
671 return "None";
672 }
673 else if (dbusSource ==
674 "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
675 {
676 return "Hdd";
677 }
678 else if (dbusSource ==
Santosh Puranika71dc0b2019-05-23 20:10:49 +0530679 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530680 {
681 return "Cd";
682 }
683 else if (dbusSource ==
684 "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
685 {
686 return "Pxe";
687 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700688 else if (dbusSource ==
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700689 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700690 {
691 return "Usb";
692 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530693 else
694 {
695 return "";
696 }
697}
698
699/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500700 * @brief Translates boot mode DBUS property value to redfish.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530701 *
702 * @param[in] dbusMode The boot mode in DBUS speak.
703 *
704 * @return Returns as a string, the boot mode in Redfish terms. If translation
705 * cannot be done, returns an empty string.
706 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000707inline std::string dbusToRfBootMode(const std::string& dbusMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530708{
709 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
710 {
711 return "None";
712 }
713 else if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
714 {
715 return "Diags";
716 }
717 else if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
718 {
719 return "BiosSetup";
720 }
721 else
722 {
723 return "";
724 }
725}
726
727/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500728 * @brief Translates boot source from Redfish to the DBus boot paths.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530729 *
730 * @param[in] rfSource The boot source in Redfish.
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700731 * @param[out] bootSource The DBus source
732 * @param[out] bootMode the DBus boot mode
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530733 *
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700734 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530735 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000736inline int assignBootParameters(std::shared_ptr<AsyncResp> aResp,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500737 const std::string& rfSource,
738 std::string& bootSource, std::string& bootMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530739{
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700740 // The caller has initialized the bootSource and bootMode to:
741 // bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
742 // bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
743 // Only modify the bootSource/bootMode variable needed to achieve the
744 // desired boot action.
745
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530746 if (rfSource == "None")
747 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700748 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530749 }
750 else if (rfSource == "Pxe")
751 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700752 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
753 }
754 else if (rfSource == "Hdd")
755 {
756 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
757 }
758 else if (rfSource == "Diags")
759 {
760 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
761 }
762 else if (rfSource == "Cd")
763 {
764 bootSource =
765 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
766 }
767 else if (rfSource == "BiosSetup")
768 {
769 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530770 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700771 else if (rfSource == "Usb")
772 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700773 bootSource =
774 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700775 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530776 else
777 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700778 BMCWEB_LOG_DEBUG << "Invalid property value for "
779 "BootSourceOverrideTarget: "
780 << bootSource;
781 messages::propertyValueNotInList(aResp->res, rfSource,
782 "BootSourceTargetOverride");
783 return -1;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530784 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700785 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530786}
787
788/**
789 * @brief Retrieves boot mode over DBUS and fills out the response
790 *
791 * @param[in] aResp Shared pointer for generating response message.
792 * @param[in] bootDbusObj The dbus object to query for boot properties.
793 *
794 * @return None.
795 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000796inline void getBootMode(std::shared_ptr<AsyncResp> aResp,
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530797 std::string bootDbusObj)
798{
799 crow::connections::systemBus->async_method_call(
800 [aResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500801 const std::variant<std::string>& bootMode) {
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530802 if (ec)
803 {
804 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
805 messages::internalError(aResp->res);
806 return;
807 }
808
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500809 const std::string* bootModeStr =
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530810 std::get_if<std::string>(&bootMode);
811
812 if (!bootModeStr)
813 {
814 messages::internalError(aResp->res);
815 return;
816 }
817
818 BMCWEB_LOG_DEBUG << "Boot mode: " << *bootModeStr;
819
820 // TODO (Santosh): Do we need to support override mode?
821 aResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = "Legacy";
822 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget@Redfish."
823 "AllowableValues"] = {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700824 "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530825
826 if (*bootModeStr !=
827 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
828 {
829 auto rfMode = dbusToRfBootMode(*bootModeStr);
830 if (!rfMode.empty())
831 {
832 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
833 rfMode;
834 }
835 }
836
837 // If the BootSourceOverrideTarget is still "None" at the end,
838 // reset the BootSourceOverrideEnabled to indicate that
839 // overrides are disabled
840 if (aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] ==
841 "None")
842 {
843 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
844 "Disabled";
845 }
846 },
847 "xyz.openbmc_project.Settings", bootDbusObj,
848 "org.freedesktop.DBus.Properties", "Get",
849 "xyz.openbmc_project.Control.Boot.Mode", "BootMode");
850}
851
852/**
853 * @brief Retrieves boot source over DBUS
854 *
855 * @param[in] aResp Shared pointer for generating response message.
856 * @param[in] oneTimeEnable Boolean to indicate boot properties are one-time.
857 *
858 * @return None.
859 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000860inline void getBootSource(std::shared_ptr<AsyncResp> aResp, bool oneTimeEnabled)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530861{
862 std::string bootDbusObj =
863 oneTimeEnabled ? "/xyz/openbmc_project/control/host0/boot/one_time"
864 : "/xyz/openbmc_project/control/host0/boot";
865
866 BMCWEB_LOG_DEBUG << "Is one time: " << oneTimeEnabled;
867 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
868 (oneTimeEnabled) ? "Once" : "Continuous";
869
870 crow::connections::systemBus->async_method_call(
871 [aResp, bootDbusObj](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500872 const std::variant<std::string>& bootSource) {
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530873 if (ec)
874 {
875 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
876 messages::internalError(aResp->res);
877 return;
878 }
879
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500880 const std::string* bootSourceStr =
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530881 std::get_if<std::string>(&bootSource);
882
883 if (!bootSourceStr)
884 {
885 messages::internalError(aResp->res);
886 return;
887 }
888 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSourceStr;
889
890 auto rfSource = dbusToRfBootSource(*bootSourceStr);
891 if (!rfSource.empty())
892 {
893 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
894 rfSource;
895 }
896 },
897 "xyz.openbmc_project.Settings", bootDbusObj,
898 "org.freedesktop.DBus.Properties", "Get",
899 "xyz.openbmc_project.Control.Boot.Source", "BootSource");
900 getBootMode(std::move(aResp), std::move(bootDbusObj));
901}
902
903/**
904 * @brief Retrieves "One time" enabled setting over DBUS and calls function to
905 * get boot source and boot mode.
906 *
907 * @param[in] aResp Shared pointer for generating response message.
908 *
909 * @return None.
910 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000911inline void getBootProperties(std::shared_ptr<AsyncResp> aResp)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530912{
913 BMCWEB_LOG_DEBUG << "Get boot information.";
914
915 crow::connections::systemBus->async_method_call(
Jennifer Leec5d03ff2019-03-08 15:42:58 -0800916 [aResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500917 const std::variant<bool>& oneTime) {
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530918 if (ec)
919 {
920 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
James Feist2a833c72019-07-19 10:17:13 -0700921 // not an error, don't have to have the interface
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530922 return;
923 }
924
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500925 const bool* oneTimePtr = std::get_if<bool>(&oneTime);
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530926
927 if (!oneTimePtr)
928 {
929 messages::internalError(aResp->res);
930 return;
931 }
932 getBootSource(aResp, *oneTimePtr);
933 },
934 "xyz.openbmc_project.Settings",
935 "/xyz/openbmc_project/control/host0/boot/one_time",
936 "org.freedesktop.DBus.Properties", "Get",
937 "xyz.openbmc_project.Object.Enable", "Enabled");
938}
939
940/**
Gunnar Millsc0557e12020-06-30 11:26:20 -0500941 * @brief Retrieves the Last Reset Time
942 *
943 * "Reset" is an overloaded term in Redfish, "Reset" includes power on
944 * and power off. Even though this is the "system" Redfish object look at the
945 * chassis D-Bus interface for the LastStateChangeTime since this has the
946 * last power operation time.
947 *
948 * @param[in] aResp Shared pointer for generating response message.
949 *
950 * @return None.
951 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000952inline void getLastResetTime(std::shared_ptr<AsyncResp> aResp)
Gunnar Millsc0557e12020-06-30 11:26:20 -0500953{
954 BMCWEB_LOG_DEBUG << "Getting System Last Reset Time";
955
956 crow::connections::systemBus->async_method_call(
957 [aResp](const boost::system::error_code ec,
958 std::variant<uint64_t>& lastResetTime) {
959 if (ec)
960 {
961 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
962 return;
963 }
964
965 const uint64_t* lastResetTimePtr =
966 std::get_if<uint64_t>(&lastResetTime);
967
968 if (!lastResetTimePtr)
969 {
970 messages::internalError(aResp->res);
971 return;
972 }
973 // LastStateChangeTime is epoch time, in milliseconds
974 // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
975 time_t lastResetTimeStamp =
976 static_cast<time_t>(*lastResetTimePtr / 1000);
977
978 // Convert to ISO 8601 standard
979 aResp->res.jsonValue["LastResetTime"] =
980 crow::utility::getDateTime(lastResetTimeStamp);
981 },
982 "xyz.openbmc_project.State.Chassis",
983 "/xyz/openbmc_project/state/chassis0",
984 "org.freedesktop.DBus.Properties", "Get",
985 "xyz.openbmc_project.State.Chassis", "LastStateChangeTime");
986}
987
988/**
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -0500989 * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
990 *
991 * @param[in] aResp Shared pointer for generating response message.
992 *
993 * @return None.
994 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000995inline void getAutomaticRetry(std::shared_ptr<AsyncResp> aResp)
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -0500996{
997 BMCWEB_LOG_DEBUG << "Get Automatic Retry policy";
998
999 crow::connections::systemBus->async_method_call(
1000 [aResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001001 std::variant<bool>& autoRebootEnabled) {
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001002 if (ec)
1003 {
1004 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
1005 return;
1006 }
1007
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001008 const bool* autoRebootEnabledPtr =
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001009 std::get_if<bool>(&autoRebootEnabled);
1010
1011 if (!autoRebootEnabledPtr)
1012 {
1013 messages::internalError(aResp->res);
1014 return;
1015 }
1016
1017 BMCWEB_LOG_DEBUG << "Auto Reboot: " << *autoRebootEnabledPtr;
1018 if (*autoRebootEnabledPtr == true)
1019 {
1020 aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
1021 "RetryAttempts";
1022 // If AutomaticRetry (AutoReboot) is enabled see how many
1023 // attempts are left
1024 crow::connections::systemBus->async_method_call(
Ed Tanouscb13a392020-07-25 19:02:03 +00001025 [aResp](const boost::system::error_code ec2,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001026 std::variant<uint32_t>& autoRebootAttemptsLeft) {
Ed Tanouscb13a392020-07-25 19:02:03 +00001027 if (ec2)
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001028 {
Ed Tanouscb13a392020-07-25 19:02:03 +00001029 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec2;
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001030 return;
1031 }
1032
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001033 const uint32_t* autoRebootAttemptsLeftPtr =
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001034 std::get_if<uint32_t>(&autoRebootAttemptsLeft);
1035
1036 if (!autoRebootAttemptsLeftPtr)
1037 {
1038 messages::internalError(aResp->res);
1039 return;
1040 }
1041
1042 BMCWEB_LOG_DEBUG << "Auto Reboot Attempts Left: "
1043 << *autoRebootAttemptsLeftPtr;
1044
1045 aResp->res
1046 .jsonValue["Boot"]
1047 ["RemainingAutomaticRetryAttempts"] =
1048 *autoRebootAttemptsLeftPtr;
1049 },
1050 "xyz.openbmc_project.State.Host",
1051 "/xyz/openbmc_project/state/host0",
1052 "org.freedesktop.DBus.Properties", "Get",
1053 "xyz.openbmc_project.Control.Boot.RebootAttempts",
1054 "AttemptsLeft");
1055 }
1056 else
1057 {
1058 aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
1059 "Disabled";
1060 }
1061
1062 // Not on D-Bus. Hardcoded here:
1063 // https://github.com/openbmc/phosphor-state-manager/blob/1dbbef42675e94fb1f78edb87d6b11380260535a/meson_options.txt#L71
1064 aResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] = 3;
Gunnar Mills69f35302020-05-17 16:06:31 -05001065
1066 // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
1067 // and RetryAttempts. OpenBMC only supports Disabled and
1068 // RetryAttempts.
1069 aResp->res.jsonValue["Boot"]["AutomaticRetryConfig@Redfish."
1070 "AllowableValues"] = {"Disabled",
1071 "RetryAttempts"};
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001072 },
1073 "xyz.openbmc_project.Settings",
1074 "/xyz/openbmc_project/control/host0/auto_reboot",
1075 "org.freedesktop.DBus.Properties", "Get",
1076 "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot");
1077}
1078
1079/**
George Liuc6a620f2020-04-10 17:18:11 +08001080 * @brief Retrieves power restore policy over DBUS.
1081 *
1082 * @param[in] aResp Shared pointer for generating response message.
1083 *
1084 * @return None.
1085 */
Ed Tanous23a21a12020-07-25 04:45:05 +00001086inline void getPowerRestorePolicy(std::shared_ptr<AsyncResp> aResp)
George Liuc6a620f2020-04-10 17:18:11 +08001087{
1088 BMCWEB_LOG_DEBUG << "Get power restore policy";
1089
1090 crow::connections::systemBus->async_method_call(
1091 [aResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001092 std::variant<std::string>& policy) {
George Liuc6a620f2020-04-10 17:18:11 +08001093 if (ec)
1094 {
1095 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1096 return;
1097 }
1098
1099 const boost::container::flat_map<std::string, std::string>
1100 policyMaps = {
1101 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1102 "AlwaysOn",
1103 "AlwaysOn"},
1104 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1105 "AlwaysOff",
1106 "AlwaysOff"},
1107 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1108 "LastState",
1109 "LastState"}};
1110
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001111 const std::string* policyPtr = std::get_if<std::string>(&policy);
George Liuc6a620f2020-04-10 17:18:11 +08001112
1113 if (!policyPtr)
1114 {
1115 messages::internalError(aResp->res);
1116 return;
1117 }
1118
1119 auto policyMapsIt = policyMaps.find(*policyPtr);
1120 if (policyMapsIt == policyMaps.end())
1121 {
1122 messages::internalError(aResp->res);
1123 return;
1124 }
1125
1126 aResp->res.jsonValue["PowerRestorePolicy"] = policyMapsIt->second;
1127 },
1128 "xyz.openbmc_project.Settings",
1129 "/xyz/openbmc_project/control/host0/power_restore_policy",
1130 "org.freedesktop.DBus.Properties", "Get",
1131 "xyz.openbmc_project.Control.Power.RestorePolicy",
1132 "PowerRestorePolicy");
1133}
1134
1135/**
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301136 * @brief Sets boot properties into DBUS object(s).
1137 *
1138 * @param[in] aResp Shared pointer for generating response message.
1139 * @param[in] oneTimeEnabled Is "one-time" setting already enabled.
1140 * @param[in] bootSource The boot source to set.
1141 * @param[in] bootEnable The source override "enable" to set.
1142 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001143 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301144 */
Ed Tanous23a21a12020-07-25 04:45:05 +00001145inline void setBootModeOrSource(std::shared_ptr<AsyncResp> aResp,
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301146 bool oneTimeEnabled,
1147 std::optional<std::string> bootSource,
1148 std::optional<std::string> bootEnable)
1149{
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001150 std::string bootSourceStr =
1151 "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
1152 std::string bootModeStr =
1153 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301154 bool oneTimeSetting = oneTimeEnabled;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001155 bool useBootSource = true;
1156
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301157 // Validate incoming parameters
1158 if (bootEnable)
1159 {
1160 if (*bootEnable == "Once")
1161 {
1162 oneTimeSetting = true;
1163 }
1164 else if (*bootEnable == "Continuous")
1165 {
1166 oneTimeSetting = false;
1167 }
1168 else if (*bootEnable == "Disabled")
1169 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001170 BMCWEB_LOG_DEBUG << "Boot source override will be disabled";
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301171 oneTimeSetting = false;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001172 useBootSource = false;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301173 }
1174 else
1175 {
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301176 BMCWEB_LOG_DEBUG << "Unsupported value for "
1177 "BootSourceOverrideEnabled: "
1178 << *bootEnable;
1179 messages::propertyValueNotInList(aResp->res, *bootEnable,
1180 "BootSourceOverrideEnabled");
1181 return;
1182 }
1183 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301184
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001185 if (bootSource && useBootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301186 {
1187 // Source target specified
1188 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource;
1189 // Figure out which DBUS interface and property to use
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001190 if (assignBootParameters(aResp, *bootSource, bootSourceStr,
1191 bootModeStr))
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301192 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001193 BMCWEB_LOG_DEBUG
1194 << "Invalid property value for BootSourceOverrideTarget: "
1195 << *bootSource;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301196 messages::propertyValueNotInList(aResp->res, *bootSource,
1197 "BootSourceTargetOverride");
1198 return;
1199 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001200 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301201
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001202 // Act on validated parameters
1203 BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
1204 BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001205 const char* bootObj =
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001206 oneTimeSetting ? "/xyz/openbmc_project/control/host0/boot/one_time"
1207 : "/xyz/openbmc_project/control/host0/boot";
1208
1209 crow::connections::systemBus->async_method_call(
1210 [aResp](const boost::system::error_code ec) {
1211 if (ec)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301212 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001213 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1214 messages::internalError(aResp->res);
1215 return;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301216 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001217 BMCWEB_LOG_DEBUG << "Boot source update done.";
1218 },
1219 "xyz.openbmc_project.Settings", bootObj,
1220 "org.freedesktop.DBus.Properties", "Set",
1221 "xyz.openbmc_project.Control.Boot.Source", "BootSource",
1222 std::variant<std::string>(bootSourceStr));
1223
1224 crow::connections::systemBus->async_method_call(
1225 [aResp](const boost::system::error_code ec) {
1226 if (ec)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301227 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001228 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1229 messages::internalError(aResp->res);
1230 return;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301231 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001232 BMCWEB_LOG_DEBUG << "Boot mode update done.";
1233 },
1234 "xyz.openbmc_project.Settings", bootObj,
1235 "org.freedesktop.DBus.Properties", "Set",
1236 "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
1237 std::variant<std::string>(bootModeStr));
1238
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301239 crow::connections::systemBus->async_method_call(
1240 [aResp{std::move(aResp)}](const boost::system::error_code ec) {
1241 if (ec)
1242 {
1243 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1244 messages::internalError(aResp->res);
1245 return;
1246 }
1247 BMCWEB_LOG_DEBUG << "Boot enable update done.";
1248 },
1249 "xyz.openbmc_project.Settings",
1250 "/xyz/openbmc_project/control/host0/boot/one_time",
1251 "org.freedesktop.DBus.Properties", "Set",
1252 "xyz.openbmc_project.Object.Enable", "Enabled",
1253 std::variant<bool>(oneTimeSetting));
1254}
1255
1256/**
1257 * @brief Retrieves "One time" enabled setting over DBUS and calls function to
1258 * set boot source/boot mode properties.
1259 *
1260 * @param[in] aResp Shared pointer for generating response message.
1261 * @param[in] bootSource The boot source from incoming RF request.
1262 * @param[in] bootEnable The boot override enable from incoming RF request.
1263 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001264 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301265 */
Ed Tanous23a21a12020-07-25 04:45:05 +00001266inline void setBootSourceProperties(std::shared_ptr<AsyncResp> aResp,
Gunnar Mills69f35302020-05-17 16:06:31 -05001267 std::optional<std::string> bootSource,
1268 std::optional<std::string> bootEnable)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301269{
1270 BMCWEB_LOG_DEBUG << "Set boot information.";
1271
1272 crow::connections::systemBus->async_method_call(
Johnathan Mantey265c1602019-08-08 11:02:51 -07001273 [aResp, bootSource{std::move(bootSource)},
Patrick Williams19bd78d2020-05-13 17:38:24 -05001274 bootEnable{std::move(bootEnable)}](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001275 const std::variant<bool>& oneTime) {
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301276 if (ec)
1277 {
1278 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1279 messages::internalError(aResp->res);
1280 return;
1281 }
1282
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001283 const bool* oneTimePtr = std::get_if<bool>(&oneTime);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301284
1285 if (!oneTimePtr)
1286 {
1287 messages::internalError(aResp->res);
1288 return;
1289 }
1290
1291 BMCWEB_LOG_DEBUG << "Got one time: " << *oneTimePtr;
1292
1293 setBootModeOrSource(aResp, *oneTimePtr, std::move(bootSource),
1294 std::move(bootEnable));
1295 },
1296 "xyz.openbmc_project.Settings",
1297 "/xyz/openbmc_project/control/host0/boot/one_time",
1298 "org.freedesktop.DBus.Properties", "Get",
1299 "xyz.openbmc_project.Object.Enable", "Enabled");
1300}
1301
George Liuc6a620f2020-04-10 17:18:11 +08001302/**
Gunnar Mills69f35302020-05-17 16:06:31 -05001303 * @brief Sets automaticRetry (Auto Reboot)
1304 *
1305 * @param[in] aResp Shared pointer for generating response message.
1306 * @param[in] automaticRetryConfig "AutomaticRetryConfig" from request.
1307 *
1308 * @return None.
1309 */
Ed Tanous23a21a12020-07-25 04:45:05 +00001310inline void setAutomaticRetry(std::shared_ptr<AsyncResp> aResp,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001311 const std::string&& automaticRetryConfig)
Gunnar Mills69f35302020-05-17 16:06:31 -05001312{
1313 BMCWEB_LOG_DEBUG << "Set Automatic Retry.";
1314
1315 // OpenBMC only supports "Disabled" and "RetryAttempts".
1316 bool autoRebootEnabled;
1317
1318 if (automaticRetryConfig == "Disabled")
1319 {
1320 autoRebootEnabled = false;
1321 }
1322 else if (automaticRetryConfig == "RetryAttempts")
1323 {
1324 autoRebootEnabled = true;
1325 }
1326 else
1327 {
1328 BMCWEB_LOG_DEBUG << "Invalid property value for "
1329 "AutomaticRetryConfig: "
1330 << automaticRetryConfig;
1331 messages::propertyValueNotInList(aResp->res, automaticRetryConfig,
1332 "AutomaticRetryConfig");
1333 return;
1334 }
1335
1336 crow::connections::systemBus->async_method_call(
1337 [aResp](const boost::system::error_code ec) {
1338 if (ec)
1339 {
1340 messages::internalError(aResp->res);
1341 return;
1342 }
1343 },
1344 "xyz.openbmc_project.Settings",
1345 "/xyz/openbmc_project/control/host0/auto_reboot",
1346 "org.freedesktop.DBus.Properties", "Set",
1347 "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
1348 std::variant<bool>(autoRebootEnabled));
1349}
1350
1351/**
George Liuc6a620f2020-04-10 17:18:11 +08001352 * @brief Sets power restore policy properties.
1353 *
1354 * @param[in] aResp Shared pointer for generating response message.
1355 * @param[in] policy power restore policy properties from request.
1356 *
1357 * @return None.
1358 */
Ed Tanous23a21a12020-07-25 04:45:05 +00001359inline void setPowerRestorePolicy(std::shared_ptr<AsyncResp> aResp,
George Liuc6a620f2020-04-10 17:18:11 +08001360 std::optional<std::string> policy)
1361{
1362 BMCWEB_LOG_DEBUG << "Set power restore policy.";
1363
1364 const boost::container::flat_map<std::string, std::string> policyMaps = {
1365 {"AlwaysOn", "xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1366 "AlwaysOn"},
1367 {"AlwaysOff", "xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1368 "AlwaysOff"},
1369 {"LastState", "xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1370 "LastState"}};
1371
1372 std::string powerRestorPolicy;
1373
1374 auto policyMapsIt = policyMaps.find(*policy);
1375 if (policyMapsIt == policyMaps.end())
1376 {
1377 messages::internalError(aResp->res);
1378 return;
1379 }
1380
1381 powerRestorPolicy = policyMapsIt->second;
1382
1383 crow::connections::systemBus->async_method_call(
1384 [aResp](const boost::system::error_code ec) {
1385 if (ec)
1386 {
1387 messages::internalError(aResp->res);
1388 return;
1389 }
1390 },
1391 "xyz.openbmc_project.Settings",
1392 "/xyz/openbmc_project/control/host0/power_restore_policy",
1393 "org.freedesktop.DBus.Properties", "Set",
1394 "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
1395 std::variant<std::string>(powerRestorPolicy));
1396}
1397
AppaRao Pulia6349912019-10-18 17:16:08 +05301398#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1399/**
1400 * @brief Retrieves provisioning status
1401 *
1402 * @param[in] aResp Shared pointer for completing asynchronous calls.
1403 *
1404 * @return None.
1405 */
Ed Tanous23a21a12020-07-25 04:45:05 +00001406inline void getProvisioningStatus(std::shared_ptr<AsyncResp> aResp)
AppaRao Pulia6349912019-10-18 17:16:08 +05301407{
1408 BMCWEB_LOG_DEBUG << "Get OEM information.";
1409 crow::connections::systemBus->async_method_call(
1410 [aResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001411 const std::vector<std::pair<std::string, VariantType>>&
1412 propertiesList) {
AppaRao Pulib99fb1a2020-07-08 16:42:48 +05301413 nlohmann::json& oemPFR =
1414 aResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
James Feist50626f42020-09-23 14:40:47 -07001415 aResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
1416 "#OemComputerSystem.OpenBmc";
1417 oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning";
1418
AppaRao Pulia6349912019-10-18 17:16:08 +05301419 if (ec)
1420 {
1421 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
AppaRao Pulib99fb1a2020-07-08 16:42:48 +05301422 // not an error, don't have to have the interface
1423 oemPFR["ProvisioningStatus"] = "NotProvisioned";
AppaRao Pulia6349912019-10-18 17:16:08 +05301424 return;
1425 }
1426
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001427 const bool* provState = nullptr;
1428 const bool* lockState = nullptr;
1429 for (const std::pair<std::string, VariantType>& property :
AppaRao Pulia6349912019-10-18 17:16:08 +05301430 propertiesList)
1431 {
1432 if (property.first == "UfmProvisioned")
1433 {
1434 provState = std::get_if<bool>(&property.second);
1435 }
1436 else if (property.first == "UfmLocked")
1437 {
1438 lockState = std::get_if<bool>(&property.second);
1439 }
1440 }
1441
1442 if ((provState == nullptr) || (lockState == nullptr))
1443 {
1444 BMCWEB_LOG_DEBUG << "Unable to get PFR attributes.";
1445 messages::internalError(aResp->res);
1446 return;
1447 }
1448
AppaRao Pulia6349912019-10-18 17:16:08 +05301449 if (*provState == true)
1450 {
1451 if (*lockState == true)
1452 {
1453 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
1454 }
1455 else
1456 {
1457 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
1458 }
1459 }
1460 else
1461 {
1462 oemPFR["ProvisioningStatus"] = "NotProvisioned";
1463 }
1464 },
1465 "xyz.openbmc_project.PFR.Manager", "/xyz/openbmc_project/pfr",
1466 "org.freedesktop.DBus.Properties", "GetAll",
1467 "xyz.openbmc_project.PFR.Attributes");
1468}
1469#endif
1470
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301471/**
Yong Li51709ff2019-09-30 14:13:04 +08001472 * @brief Translates watchdog timeout action DBUS property value to redfish.
1473 *
1474 * @param[in] dbusAction The watchdog timeout action in D-BUS.
1475 *
1476 * @return Returns as a string, the timeout action in Redfish terms. If
1477 * translation cannot be done, returns an empty string.
1478 */
Ed Tanous23a21a12020-07-25 04:45:05 +00001479inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
Yong Li51709ff2019-09-30 14:13:04 +08001480{
1481 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
1482 {
1483 return "None";
1484 }
1485 else if (dbusAction ==
1486 "xyz.openbmc_project.State.Watchdog.Action.HardReset")
1487 {
1488 return "ResetSystem";
1489 }
1490 else if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
1491 {
1492 return "PowerDown";
1493 }
1494 else if (dbusAction ==
1495 "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
1496 {
1497 return "PowerCycle";
1498 }
1499
1500 return "";
1501}
1502
1503/**
Yong Lic45f0082019-10-10 14:19:01 +08001504 *@brief Translates timeout action from Redfish to DBUS property value.
1505 *
1506 *@param[in] rfAction The timeout action in Redfish.
1507 *
1508 *@return Returns as a string, the time_out action as expected by DBUS.
1509 *If translation cannot be done, returns an empty string.
1510 */
1511
Ed Tanous23a21a12020-07-25 04:45:05 +00001512inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
Yong Lic45f0082019-10-10 14:19:01 +08001513{
1514 if (rfAction == "None")
1515 {
1516 return "xyz.openbmc_project.State.Watchdog.Action.None";
1517 }
1518 else if (rfAction == "PowerCycle")
1519 {
1520 return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
1521 }
1522 else if (rfAction == "PowerDown")
1523 {
1524 return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
1525 }
1526 else if (rfAction == "ResetSystem")
1527 {
1528 return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
1529 }
1530
1531 return "";
1532}
1533
1534/**
Yong Li51709ff2019-09-30 14:13:04 +08001535 * @brief Retrieves host watchdog timer properties over DBUS
1536 *
1537 * @param[in] aResp Shared pointer for completing asynchronous calls.
1538 *
1539 * @return None.
1540 */
Ed Tanous23a21a12020-07-25 04:45:05 +00001541inline void getHostWatchdogTimer(std::shared_ptr<AsyncResp> aResp)
Yong Li51709ff2019-09-30 14:13:04 +08001542{
1543 BMCWEB_LOG_DEBUG << "Get host watchodg";
1544 crow::connections::systemBus->async_method_call(
1545 [aResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001546 PropertiesType& properties) {
Yong Li51709ff2019-09-30 14:13:04 +08001547 if (ec)
1548 {
1549 // watchdog service is stopped
1550 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1551 return;
1552 }
1553
1554 BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop.";
1555
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001556 nlohmann::json& hostWatchdogTimer =
Yong Li51709ff2019-09-30 14:13:04 +08001557 aResp->res.jsonValue["HostWatchdogTimer"];
1558
1559 // watchdog service is running/enabled
1560 hostWatchdogTimer["Status"]["State"] = "Enabled";
1561
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001562 for (const auto& property : properties)
Yong Li51709ff2019-09-30 14:13:04 +08001563 {
1564 BMCWEB_LOG_DEBUG << "prop=" << property.first;
1565 if (property.first == "Enabled")
1566 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001567 const bool* state = std::get_if<bool>(&property.second);
Yong Li51709ff2019-09-30 14:13:04 +08001568
1569 if (!state)
1570 {
1571 messages::internalError(aResp->res);
1572 continue;
1573 }
1574
1575 hostWatchdogTimer["FunctionEnabled"] = *state;
1576 }
1577 else if (property.first == "ExpireAction")
1578 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001579 const std::string* s =
Yong Li51709ff2019-09-30 14:13:04 +08001580 std::get_if<std::string>(&property.second);
1581 if (!s)
1582 {
1583 messages::internalError(aResp->res);
1584 continue;
1585 }
1586
1587 std::string action = dbusToRfWatchdogAction(*s);
1588 if (action.empty())
1589 {
1590 messages::internalError(aResp->res);
1591 continue;
1592 }
1593 hostWatchdogTimer["TimeoutAction"] = action;
1594 }
1595 }
1596 },
1597 "xyz.openbmc_project.Watchdog", "/xyz/openbmc_project/watchdog/host0",
1598 "org.freedesktop.DBus.Properties", "GetAll",
1599 "xyz.openbmc_project.State.Watchdog");
1600}
1601
1602/**
Yong Lic45f0082019-10-10 14:19:01 +08001603 * @brief Sets Host WatchDog Timer properties.
1604 *
1605 * @param[in] aResp Shared pointer for generating response message.
1606 * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming
1607 * RF request.
1608 * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
1609 *
1610 * @return None.
1611 */
Ed Tanous23a21a12020-07-25 04:45:05 +00001612inline void setWDTProperties(std::shared_ptr<AsyncResp> aResp,
Yong Lic45f0082019-10-10 14:19:01 +08001613 const std::optional<bool> wdtEnable,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001614 const std::optional<std::string>& wdtTimeOutAction)
Yong Lic45f0082019-10-10 14:19:01 +08001615{
1616 BMCWEB_LOG_DEBUG << "Set host watchdog";
1617
1618 if (wdtTimeOutAction)
1619 {
1620 std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
1621 // check if TimeOut Action is Valid
1622 if (wdtTimeOutActStr.empty())
1623 {
1624 BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: "
1625 << *wdtTimeOutAction;
1626 messages::propertyValueNotInList(aResp->res, *wdtTimeOutAction,
1627 "TimeoutAction");
1628 return;
1629 }
1630
1631 crow::connections::systemBus->async_method_call(
1632 [aResp](const boost::system::error_code ec) {
1633 if (ec)
1634 {
1635 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1636 messages::internalError(aResp->res);
1637 return;
1638 }
1639 },
1640 "xyz.openbmc_project.Watchdog",
1641 "/xyz/openbmc_project/watchdog/host0",
1642 "org.freedesktop.DBus.Properties", "Set",
1643 "xyz.openbmc_project.State.Watchdog", "ExpireAction",
1644 std::variant<std::string>(wdtTimeOutActStr));
1645 }
1646
1647 if (wdtEnable)
1648 {
1649 crow::connections::systemBus->async_method_call(
1650 [aResp](const boost::system::error_code ec) {
1651 if (ec)
1652 {
1653 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1654 messages::internalError(aResp->res);
1655 return;
1656 }
1657 },
1658 "xyz.openbmc_project.Watchdog",
1659 "/xyz/openbmc_project/watchdog/host0",
1660 "org.freedesktop.DBus.Properties", "Set",
1661 "xyz.openbmc_project.State.Watchdog", "Enabled",
1662 std::variant<bool>(*wdtEnable));
1663 }
1664}
1665
1666/**
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001667 * SystemsCollection derived class for delivering ComputerSystems Collection
1668 * Schema
1669 */
Ed Tanous1abe55e2018-09-05 08:30:59 -07001670class SystemsCollection : public Node
1671{
1672 public:
Ed Tanous52cc1122020-07-18 13:51:21 -07001673 SystemsCollection(App& app) : Node(app, "/redfish/v1/Systems/")
Ed Tanous1abe55e2018-09-05 08:30:59 -07001674 {
Ed Tanous1abe55e2018-09-05 08:30:59 -07001675 entityPrivileges = {
1676 {boost::beast::http::verb::get, {{"Login"}}},
1677 {boost::beast::http::verb::head, {{"Login"}}},
1678 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1679 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1680 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1681 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1682 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001683
Ed Tanous1abe55e2018-09-05 08:30:59 -07001684 private:
Ed Tanouscb13a392020-07-25 19:02:03 +00001685 void doGet(crow::Response& res, const crow::Request&,
1686 const std::vector<std::string>&) override
Ed Tanous1abe55e2018-09-05 08:30:59 -07001687 {
Sunitha Harish462023a2020-02-19 08:34:59 -06001688 std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
Ed Tanous0f74e642018-11-12 15:17:05 -08001689 res.jsonValue["@odata.type"] =
1690 "#ComputerSystemCollection.ComputerSystemCollection";
1691 res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
Ed Tanous0f74e642018-11-12 15:17:05 -08001692 res.jsonValue["Name"] = "Computer System Collection";
Sunitha Harish462023a2020-02-19 08:34:59 -06001693
1694 crow::connections::systemBus->async_method_call(
1695 [asyncResp](const boost::system::error_code ec,
Ed Tanouscb13a392020-07-25 19:02:03 +00001696 const std::variant<std::string>& /*hostName*/) {
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001697 nlohmann::json& iface_array =
Sunitha Harish462023a2020-02-19 08:34:59 -06001698 asyncResp->res.jsonValue["Members"];
1699 iface_array = nlohmann::json::array();
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001700 auto& count = asyncResp->res.jsonValue["Members@odata.count"];
Sunitha Harish462023a2020-02-19 08:34:59 -06001701 count = 0;
Ed Tanouscb13a392020-07-25 19:02:03 +00001702 iface_array.push_back(
1703 {{"@odata.id", "/redfish/v1/Systems/system"}});
1704 if (!ec)
Sunitha Harish462023a2020-02-19 08:34:59 -06001705 {
Ed Tanouscb13a392020-07-25 19:02:03 +00001706 BMCWEB_LOG_DEBUG << "Hypervisor is available";
Sunitha Harish462023a2020-02-19 08:34:59 -06001707 iface_array.push_back(
Ed Tanouscb13a392020-07-25 19:02:03 +00001708 {{"@odata.id", "/redfish/v1/Systems/hypervisor"}});
Sunitha Harish462023a2020-02-19 08:34:59 -06001709 count = iface_array.size();
1710 return;
1711 }
Sunitha Harish462023a2020-02-19 08:34:59 -06001712 },
Sunitha Harish8e651fb2020-06-17 06:06:25 -05001713 "xyz.openbmc_project.Settings",
1714 "/xyz/openbmc_project/network/hypervisor",
Sunitha Harish462023a2020-02-19 08:34:59 -06001715 "org.freedesktop.DBus.Properties", "Get",
1716 "xyz.openbmc_project.Network.SystemConfiguration", "HostName");
Ed Tanous1abe55e2018-09-05 08:30:59 -07001717 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001718};
1719
1720/**
Ed Tanouscc340dd2018-08-29 13:43:38 -07001721 * SystemActionsReset class supports handle POST method for Reset action.
1722 * The class retrieves and sends data directly to D-Bus.
1723 */
1724class SystemActionsReset : public Node
1725{
1726 public:
Ed Tanous52cc1122020-07-18 13:51:21 -07001727 SystemActionsReset(App& app) :
Ed Tanous029573d2019-02-01 10:57:49 -08001728 Node(app, "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/")
Ed Tanouscc340dd2018-08-29 13:43:38 -07001729 {
1730 entityPrivileges = {
1731 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1732 }
1733
1734 private:
1735 /**
1736 * Function handles POST method request.
1737 * Analyzes POST body message before sends Reset request data to D-Bus.
1738 */
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001739 void doPost(crow::Response& res, const crow::Request& req,
Ed Tanouscb13a392020-07-25 19:02:03 +00001740 const std::vector<std::string>&) override
Ed Tanouscc340dd2018-08-29 13:43:38 -07001741 {
Ed Tanous9712f8a2018-09-21 13:38:49 -07001742 auto asyncResp = std::make_shared<AsyncResp>(res);
1743
1744 std::string resetType;
1745 if (!json_util::readJson(req, res, "ResetType", resetType))
Ed Tanouscc340dd2018-08-29 13:43:38 -07001746 {
1747 return;
1748 }
1749
Jason M. Billsd22c8392019-06-03 13:59:03 -07001750 // Get the command and host vs. chassis
Ed Tanous9712f8a2018-09-21 13:38:49 -07001751 std::string command;
Jason M. Billsd22c8392019-06-03 13:59:03 -07001752 bool hostCommand;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001753 if (resetType == "On")
1754 {
1755 command = "xyz.openbmc_project.State.Host.Transition.On";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001756 hostCommand = true;
1757 }
1758 else if (resetType == "ForceOff")
1759 {
1760 command = "xyz.openbmc_project.State.Chassis.Transition.Off";
1761 hostCommand = false;
1762 }
1763 else if (resetType == "ForceOn")
1764 {
1765 command = "xyz.openbmc_project.State.Host.Transition.On";
1766 hostCommand = true;
1767 }
1768 else if (resetType == "ForceRestart")
1769 {
Jason M. Bills86a08512020-02-04 13:15:49 -08001770 command =
1771 "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
1772 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001773 }
1774 else if (resetType == "GracefulShutdown")
1775 {
1776 command = "xyz.openbmc_project.State.Host.Transition.Off";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001777 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001778 }
1779 else if (resetType == "GracefulRestart")
1780 {
Jason M. Bills86a08512020-02-04 13:15:49 -08001781 command =
1782 "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001783 hostCommand = true;
1784 }
1785 else if (resetType == "PowerCycle")
1786 {
Jason M. Bills86a08512020-02-04 13:15:49 -08001787 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
1788 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001789 }
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001790 else if (resetType == "Nmi")
1791 {
1792 doNMI(asyncResp);
1793 return;
1794 }
Ed Tanous9712f8a2018-09-21 13:38:49 -07001795 else
1796 {
Jason M. Billsf12894f2018-10-09 12:45:45 -07001797 messages::actionParameterUnknown(res, "Reset", resetType);
Ed Tanous9712f8a2018-09-21 13:38:49 -07001798 return;
1799 }
1800
Jason M. Billsd22c8392019-06-03 13:59:03 -07001801 if (hostCommand)
1802 {
1803 crow::connections::systemBus->async_method_call(
1804 [asyncResp, resetType](const boost::system::error_code ec) {
1805 if (ec)
1806 {
1807 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1808 if (ec.value() == boost::asio::error::invalid_argument)
1809 {
1810 messages::actionParameterNotSupported(
1811 asyncResp->res, resetType, "Reset");
1812 }
1813 else
1814 {
1815 messages::internalError(asyncResp->res);
1816 }
1817 return;
1818 }
1819 messages::success(asyncResp->res);
1820 },
1821 "xyz.openbmc_project.State.Host",
1822 "/xyz/openbmc_project/state/host0",
1823 "org.freedesktop.DBus.Properties", "Set",
1824 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
1825 std::variant<std::string>{command});
1826 }
1827 else
1828 {
1829 crow::connections::systemBus->async_method_call(
1830 [asyncResp, resetType](const boost::system::error_code ec) {
1831 if (ec)
1832 {
1833 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1834 if (ec.value() == boost::asio::error::invalid_argument)
1835 {
1836 messages::actionParameterNotSupported(
1837 asyncResp->res, resetType, "Reset");
1838 }
1839 else
1840 {
1841 messages::internalError(asyncResp->res);
1842 }
1843 return;
1844 }
1845 messages::success(asyncResp->res);
1846 },
1847 "xyz.openbmc_project.State.Chassis",
1848 "/xyz/openbmc_project/state/chassis0",
1849 "org.freedesktop.DBus.Properties", "Set",
1850 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
1851 std::variant<std::string>{command});
1852 }
Ed Tanouscc340dd2018-08-29 13:43:38 -07001853 }
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001854 /**
1855 * Function transceives data with dbus directly.
1856 */
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001857 void doNMI(const std::shared_ptr<AsyncResp>& asyncResp)
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001858 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001859 constexpr char const* serviceName =
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001860 "xyz.openbmc_project.Control.Host.NMI";
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001861 constexpr char const* objectPath =
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001862 "/xyz/openbmc_project/control/host0/nmi";
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001863 constexpr char const* interfaceName =
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001864 "xyz.openbmc_project.Control.Host.NMI";
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001865 constexpr char const* method = "NMI";
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001866
1867 crow::connections::systemBus->async_method_call(
1868 [asyncResp](const boost::system::error_code ec) {
1869 if (ec)
1870 {
1871 BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
1872 messages::internalError(asyncResp->res);
1873 return;
1874 }
1875 messages::success(asyncResp->res);
1876 },
1877 serviceName, objectPath, interfaceName, method);
1878 }
Ed Tanouscc340dd2018-08-29 13:43:38 -07001879};
1880
1881/**
Ed Tanous66173382018-08-15 18:20:59 -07001882 * Systems derived class for delivering Computer Systems Schema.
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001883 */
Ed Tanous1abe55e2018-09-05 08:30:59 -07001884class Systems : public Node
1885{
1886 public:
1887 /*
1888 * Default Constructor
1889 */
Ed Tanous52cc1122020-07-18 13:51:21 -07001890 Systems(App& app) : Node(app, "/redfish/v1/Systems/system/")
Ed Tanous1abe55e2018-09-05 08:30:59 -07001891 {
Ed Tanous1abe55e2018-09-05 08:30:59 -07001892 entityPrivileges = {
1893 {boost::beast::http::verb::get, {{"Login"}}},
1894 {boost::beast::http::verb::head, {{"Login"}}},
1895 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1896 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1897 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1898 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001899 }
1900
Ed Tanous1abe55e2018-09-05 08:30:59 -07001901 private:
Ed Tanous1abe55e2018-09-05 08:30:59 -07001902 /**
1903 * Functions triggers appropriate requests on DBus
1904 */
Ed Tanouscb13a392020-07-25 19:02:03 +00001905 void doGet(crow::Response& res, const crow::Request&,
1906 const std::vector<std::string>&) override
Ed Tanous1abe55e2018-09-05 08:30:59 -07001907 {
Gunnar Millsc0557e12020-06-30 11:26:20 -05001908 res.jsonValue["@odata.type"] = "#ComputerSystem.v1_12_0.ComputerSystem";
Gunnar Mills450a25c2020-04-14 21:34:07 -05001909 res.jsonValue["Name"] = "system";
Ed Tanous029573d2019-02-01 10:57:49 -08001910 res.jsonValue["Id"] = "system";
Ed Tanous0f74e642018-11-12 15:17:05 -08001911 res.jsonValue["SystemType"] = "Physical";
1912 res.jsonValue["Description"] = "Computer System";
Ed Tanous0f74e642018-11-12 15:17:05 -08001913 res.jsonValue["ProcessorSummary"]["Count"] = 0;
1914 res.jsonValue["ProcessorSummary"]["Status"]["State"] = "Disabled";
Cheng C Yang5fd7ba62019-11-28 15:58:08 +08001915 res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = uint64_t(0);
Ed Tanous0f74e642018-11-12 15:17:05 -08001916 res.jsonValue["MemorySummary"]["Status"]["State"] = "Disabled";
Ed Tanous029573d2019-02-01 10:57:49 -08001917 res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
Ed Tanous04a258f2018-10-15 08:00:41 -07001918
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001919 res.jsonValue["Processors"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001920 {"@odata.id", "/redfish/v1/Systems/system/Processors"}};
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001921 res.jsonValue["Memory"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001922 {"@odata.id", "/redfish/v1/Systems/system/Memory"}};
Nikhil Potadea25aecc2019-08-23 16:35:26 -07001923 res.jsonValue["Storage"] = {
1924 {"@odata.id", "/redfish/v1/Systems/system/Storage"}};
Ed Tanous029573d2019-02-01 10:57:49 -08001925
Ed Tanouscc340dd2018-08-29 13:43:38 -07001926 res.jsonValue["Actions"]["#ComputerSystem.Reset"] = {
1927 {"target",
Ed Tanous029573d2019-02-01 10:57:49 -08001928 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"},
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05301929 {"@Redfish.ActionInfo",
1930 "/redfish/v1/Systems/system/ResetActionInfo"}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001931
Jason M. Billsc4bf6372018-11-05 13:48:27 -08001932 res.jsonValue["LogServices"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001933 {"@odata.id", "/redfish/v1/Systems/system/LogServices"}};
Jason M. Billsc4bf6372018-11-05 13:48:27 -08001934
Carol Wangd82a3ac2019-11-21 13:56:38 +08001935 res.jsonValue["Bios"] = {
1936 {"@odata.id", "/redfish/v1/Systems/system/Bios"}};
1937
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001938 res.jsonValue["Links"]["ManagedBy"] = {
1939 {{"@odata.id", "/redfish/v1/Managers/bmc"}}};
1940
1941 res.jsonValue["Status"] = {
1942 {"Health", "OK"},
1943 {"State", "Enabled"},
1944 };
Ed Tanousa0803ef2018-08-29 13:29:23 -07001945 auto asyncResp = std::make_shared<AsyncResp>(res);
Ed Tanous1abe55e2018-09-05 08:30:59 -07001946
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001947 constexpr const std::array<const char*, 4> inventoryForSystems = {
James Feistb49ac872019-05-21 15:12:01 -07001948 "xyz.openbmc_project.Inventory.Item.Dimm",
James Feist2ad9c2f2019-10-29 16:26:48 -07001949 "xyz.openbmc_project.Inventory.Item.Cpu",
James Feiste284a7c2019-11-20 16:20:23 -08001950 "xyz.openbmc_project.Inventory.Item.Drive",
1951 "xyz.openbmc_project.Inventory.Item.StorageController"};
James Feistb49ac872019-05-21 15:12:01 -07001952
1953 auto health = std::make_shared<HealthPopulate>(asyncResp);
1954 crow::connections::systemBus->async_method_call(
1955 [health](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001956 std::vector<std::string>& resp) {
James Feistb49ac872019-05-21 15:12:01 -07001957 if (ec)
1958 {
1959 // no inventory
1960 return;
1961 }
1962
1963 health->inventory = std::move(resp);
1964 },
1965 "xyz.openbmc_project.ObjectMapper",
1966 "/xyz/openbmc_project/object_mapper",
1967 "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", "/",
1968 int32_t(0), inventoryForSystems);
1969
1970 health->populate();
1971
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001972 getMainChassisId(asyncResp, [](const std::string& chassisId,
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001973 std::shared_ptr<AsyncResp> aRsp) {
1974 aRsp->res.jsonValue["Links"]["Chassis"] = {
1975 {{"@odata.id", "/redfish/v1/Chassis/" + chassisId}}};
1976 });
AppaRao Pulia3002222019-11-12 21:32:59 +05301977
1978 getIndicatorLedState(asyncResp);
James Feist5bc2dc82019-10-22 14:33:16 -07001979 getComputerSystem(asyncResp, health);
Ed Tanous6c34de42018-08-29 13:37:36 -07001980 getHostState(asyncResp);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301981 getBootProperties(asyncResp);
Jason M. Billsadbe1922019-10-14 15:44:35 -07001982 getPCIeDeviceList(asyncResp, "PCIeDevices");
Yong Li51709ff2019-09-30 14:13:04 +08001983 getHostWatchdogTimer(asyncResp);
George Liuc6a620f2020-04-10 17:18:11 +08001984 getPowerRestorePolicy(asyncResp);
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001985 getAutomaticRetry(asyncResp);
Gunnar Millsc0557e12020-06-30 11:26:20 -05001986 getLastResetTime(asyncResp);
AppaRao Pulia6349912019-10-18 17:16:08 +05301987#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1988 getProvisioningStatus(asyncResp);
1989#endif
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001990 }
1991
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001992 void doPatch(crow::Response& res, const crow::Request& req,
Ed Tanouscb13a392020-07-25 19:02:03 +00001993 const std::vector<std::string>&) override
Ed Tanous1abe55e2018-09-05 08:30:59 -07001994 {
Santosh Puranikcde19e52019-02-20 00:10:56 +05301995 std::optional<std::string> indicatorLed;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301996 std::optional<nlohmann::json> bootProps;
Yong Lic45f0082019-10-10 14:19:01 +08001997 std::optional<nlohmann::json> wdtTimerProps;
George Liuc6a620f2020-04-10 17:18:11 +08001998 std::optional<std::string> powerRestorePolicy;
Santosh Puranik41352c22019-07-03 05:35:49 -05001999 auto asyncResp = std::make_shared<AsyncResp>(res);
2000
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07002001 if (!json_util::readJson(req, res, "IndicatorLED", indicatorLed, "Boot",
George Liuc6a620f2020-04-10 17:18:11 +08002002 bootProps, "WatchdogTimer", wdtTimerProps,
2003 "PowerRestorePolicy", powerRestorePolicy))
Ed Tanous66173382018-08-15 18:20:59 -07002004 {
Ed Tanous9712f8a2018-09-21 13:38:49 -07002005 return;
2006 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05302007
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07002008 res.result(boost::beast::http::status::no_content);
Yong Lic45f0082019-10-10 14:19:01 +08002009
2010 if (wdtTimerProps)
2011 {
2012 std::optional<bool> wdtEnable;
2013 std::optional<std::string> wdtTimeOutAction;
2014
2015 if (!json_util::readJson(*wdtTimerProps, asyncResp->res,
2016 "FunctionEnabled", wdtEnable,
2017 "TimeoutAction", wdtTimeOutAction))
2018 {
2019 return;
2020 }
2021 setWDTProperties(asyncResp, std::move(wdtEnable),
2022 std::move(wdtTimeOutAction));
2023 }
2024
Santosh Puranik491d8ee2019-02-06 19:46:56 +05302025 if (bootProps)
2026 {
2027 std::optional<std::string> bootSource;
2028 std::optional<std::string> bootEnable;
Gunnar Mills69f35302020-05-17 16:06:31 -05002029 std::optional<std::string> automaticRetryConfig;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05302030
Gunnar Mills69f35302020-05-17 16:06:31 -05002031 if (!json_util::readJson(
2032 *bootProps, asyncResp->res, "BootSourceOverrideTarget",
2033 bootSource, "BootSourceOverrideEnabled", bootEnable,
2034 "AutomaticRetryConfig", automaticRetryConfig))
Santosh Puranik491d8ee2019-02-06 19:46:56 +05302035 {
2036 return;
2037 }
Gunnar Mills69f35302020-05-17 16:06:31 -05002038 if (bootSource || bootEnable)
2039 {
2040 setBootSourceProperties(asyncResp, std::move(bootSource),
2041 std::move(bootEnable));
2042 }
2043 if (automaticRetryConfig)
2044 {
2045 setAutomaticRetry(asyncResp, std::move(*automaticRetryConfig));
2046 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05302047 }
Johnathan Mantey265c1602019-08-08 11:02:51 -07002048
Ed Tanous9712f8a2018-09-21 13:38:49 -07002049 if (indicatorLed)
2050 {
AppaRao Pulia3002222019-11-12 21:32:59 +05302051 setIndicatorLedState(asyncResp, std::move(*indicatorLed));
Ed Tanous1abe55e2018-09-05 08:30:59 -07002052 }
George Liuc6a620f2020-04-10 17:18:11 +08002053
2054 if (powerRestorePolicy)
2055 {
2056 setPowerRestorePolicy(asyncResp, std::move(*powerRestorePolicy));
2057 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002058 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002059};
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05302060
2061/**
2062 * SystemResetActionInfo derived class for delivering Computer Systems
2063 * ResetType AllowableValues using ResetInfo schema.
2064 */
2065class SystemResetActionInfo : public Node
2066{
2067 public:
2068 /*
2069 * Default Constructor
2070 */
Ed Tanous52cc1122020-07-18 13:51:21 -07002071 SystemResetActionInfo(App& app) :
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05302072 Node(app, "/redfish/v1/Systems/system/ResetActionInfo/")
2073 {
2074 entityPrivileges = {
2075 {boost::beast::http::verb::get, {{"Login"}}},
2076 {boost::beast::http::verb::head, {{"Login"}}},
2077 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
2078 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
2079 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
2080 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
2081 }
2082
2083 private:
2084 /**
2085 * Functions triggers appropriate requests on DBus
2086 */
Ed Tanouscb13a392020-07-25 19:02:03 +00002087 void doGet(crow::Response& res, const crow::Request&,
2088 const std::vector<std::string>&) override
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05302089 {
2090 res.jsonValue = {
2091 {"@odata.type", "#ActionInfo.v1_1_2.ActionInfo"},
2092 {"@odata.id", "/redfish/v1/Systems/system/ResetActionInfo"},
2093 {"Name", "Reset Action Info"},
2094 {"Id", "ResetActionInfo"},
2095 {"Parameters",
2096 {{{"Name", "ResetType"},
2097 {"Required", true},
2098 {"DataType", "String"},
2099 {"AllowableValues",
2100 {"On", "ForceOff", "ForceOn", "ForceRestart", "GracefulRestart",
2101 "GracefulShutdown", "PowerCycle", "Nmi"}}}}}};
2102 res.end();
2103 }
2104};
Ed Tanous1abe55e2018-09-05 08:30:59 -07002105} // namespace redfish