blob: 80d3e054c535dfd00a0f5d7fe5a80e1d87b1506e [file] [log] [blame]
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001/*
2// Copyright (c) 2018 Intel Corporation
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15*/
16#pragma once
17
James Feistb49ac872019-05-21 15:12:01 -070018#include "health.hpp"
James Feist1c8fba92019-12-20 15:12:07 -080019#include "led.hpp"
Jason M. Billsf5c9f8b2018-12-18 16:51:18 -080020#include "pcie.hpp"
Jennifer Leec5d03ff2019-03-08 15:42:58 -080021#include "redfish_util.hpp"
22
Ed Tanous9712f8a2018-09-21 13:38:49 -070023#include <boost/container/flat_map.hpp>
24#include <node.hpp>
Andrew Geisslercb7e1e72019-02-19 13:05:38 -060025#include <utils/fw_utils.hpp>
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020026#include <utils/json_utils.hpp>
Gunnar Mills1214b7e2020-06-04 10:11:30 -050027
Ed Tanousabf2add2019-01-22 16:40:12 -080028#include <variant>
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020029
Ed Tanous1abe55e2018-09-05 08:30:59 -070030namespace redfish
31{
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020032
Alpana Kumari9d3ae102019-04-12 06:49:32 -050033/**
34 * @brief Updates the Functional State of DIMMs
35 *
36 * @param[in] aResp Shared pointer for completing asynchronous calls
37 * @param[in] dimmState Dimm's Functional state, true/false
38 *
39 * @return None.
40 */
Ed Tanousb5a76932020-09-29 16:16:58 -070041inline void updateDimmProperties(const std::shared_ptr<AsyncResp>& aResp,
Ed Tanous23a21a12020-07-25 04:45:05 +000042 const std::variant<bool>& dimmState)
Alpana Kumari9d3ae102019-04-12 06:49:32 -050043{
Gunnar Mills1214b7e2020-06-04 10:11:30 -050044 const bool* isDimmFunctional = std::get_if<bool>(&dimmState);
Alpana Kumari9d3ae102019-04-12 06:49:32 -050045 if (isDimmFunctional == nullptr)
46 {
47 messages::internalError(aResp->res);
48 return;
49 }
Gunnar Mills698654b2019-10-16 13:17:37 -050050 BMCWEB_LOG_DEBUG << "Dimm Functional: " << *isDimmFunctional;
Alpana Kumari9d3ae102019-04-12 06:49:32 -050051
Gunnar Mills4e0453b2020-07-08 14:00:30 -050052 // Set it as Enabled if at least one DIMM is functional
Alpana Kumari9d3ae102019-04-12 06:49:32 -050053 // Update STATE only if previous State was DISABLED and current Dimm is
54 // ENABLED.
Gunnar Mills1214b7e2020-06-04 10:11:30 -050055 nlohmann::json& prevMemSummary =
Alpana Kumari9d3ae102019-04-12 06:49:32 -050056 aResp->res.jsonValue["MemorySummary"]["Status"]["State"];
57 if (prevMemSummary == "Disabled")
58 {
59 if (*isDimmFunctional == true)
60 {
61 aResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
62 "Enabled";
63 }
64 }
65}
66
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050067/*
68 * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState
69 *
70 * @param[in] aResp Shared pointer for completing asynchronous calls
71 * @param[in] cpuPresenceState CPU present or not
72 *
73 * @return None.
74 */
Ed Tanousb5a76932020-09-29 16:16:58 -070075inline void modifyCpuPresenceState(const std::shared_ptr<AsyncResp>& aResp,
Ed Tanous23a21a12020-07-25 04:45:05 +000076 const std::variant<bool>& cpuPresenceState)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050077{
Gunnar Mills1214b7e2020-06-04 10:11:30 -050078 const bool* isCpuPresent = std::get_if<bool>(&cpuPresenceState);
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050079
80 if (isCpuPresent == nullptr)
81 {
82 messages::internalError(aResp->res);
83 return;
84 }
Gunnar Mills698654b2019-10-16 13:17:37 -050085 BMCWEB_LOG_DEBUG << "Cpu Present: " << *isCpuPresent;
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050086
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050087 if (*isCpuPresent == true)
88 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -050089 nlohmann::json& procCount =
James Feistb4b95952019-12-05 15:01:55 -080090 aResp->res.jsonValue["ProcessorSummary"]["Count"];
91 auto procCountPtr =
Gunnar Mills1214b7e2020-06-04 10:11:30 -050092 procCount.get_ptr<nlohmann::json::number_integer_t*>();
James Feistb4b95952019-12-05 15:01:55 -080093 if (procCountPtr != nullptr)
94 {
95 // shouldn't be possible to be nullptr
96 *procCountPtr += 1;
97 }
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050098 }
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050099}
100
101/*
102 * @brief Update "ProcessorSummary" "Status" "State" based on
103 * CPU Functional State
104 *
105 * @param[in] aResp Shared pointer for completing asynchronous calls
106 * @param[in] cpuFunctionalState is CPU functional true/false
107 *
108 * @return None.
109 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000110inline void
Ed Tanousb5a76932020-09-29 16:16:58 -0700111 modifyCpuFunctionalState(const std::shared_ptr<AsyncResp>& aResp,
Ed Tanous23a21a12020-07-25 04:45:05 +0000112 const std::variant<bool>& cpuFunctionalState)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500113{
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500114 const bool* isCpuFunctional = std::get_if<bool>(&cpuFunctionalState);
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500115
116 if (isCpuFunctional == nullptr)
117 {
118 messages::internalError(aResp->res);
119 return;
120 }
Gunnar Mills698654b2019-10-16 13:17:37 -0500121 BMCWEB_LOG_DEBUG << "Cpu Functional: " << *isCpuFunctional;
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500122
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500123 nlohmann::json& prevProcState =
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500124 aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"];
125
Gunnar Mills4e0453b2020-07-08 14:00:30 -0500126 // Set it as Enabled if at least one CPU is functional
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500127 // Update STATE only if previous State was Non_Functional and current CPU is
128 // Functional.
129 if (prevProcState == "Disabled")
130 {
131 if (*isCpuFunctional == true)
132 {
133 aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
134 "Enabled";
135 }
136 }
137}
138
139/*
Ed Tanous6c34de42018-08-29 13:37:36 -0700140 * @brief Retrieves computer system properties over dbus
141 *
142 * @param[in] aResp Shared pointer for completing asynchronous calls
143 * @param[in] name Computer system name from request
144 *
145 * @return None.
146 */
Ed Tanousb5a76932020-09-29 16:16:58 -0700147inline void
148 getComputerSystem(const std::shared_ptr<AsyncResp>& aResp,
149 const std::shared_ptr<HealthPopulate>& systemHealth)
Ed Tanous6c34de42018-08-29 13:37:36 -0700150{
Ed Tanous6c34de42018-08-29 13:37:36 -0700151 BMCWEB_LOG_DEBUG << "Get available system components.";
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500152
Ed Tanous6c34de42018-08-29 13:37:36 -0700153 crow::connections::systemBus->async_method_call(
James Feist5bc2dc82019-10-22 14:33:16 -0700154 [aResp, systemHealth](
Ed Tanous6c34de42018-08-29 13:37:36 -0700155 const boost::system::error_code ec,
156 const std::vector<std::pair<
157 std::string,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500158 std::vector<std::pair<std::string, std::vector<std::string>>>>>&
159 subtree) {
Ed Tanous6c34de42018-08-29 13:37:36 -0700160 if (ec)
161 {
162 BMCWEB_LOG_DEBUG << "DBUS response error";
Jason M. Billsf12894f2018-10-09 12:45:45 -0700163 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700164 return;
165 }
Ed Tanous6c34de42018-08-29 13:37:36 -0700166 // Iterate over all retrieved ObjectPaths.
167 for (const std::pair<std::string,
168 std::vector<std::pair<
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500169 std::string, std::vector<std::string>>>>&
170 object : subtree)
Ed Tanous6c34de42018-08-29 13:37:36 -0700171 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500172 const std::string& path = object.first;
Ed Tanous6c34de42018-08-29 13:37:36 -0700173 BMCWEB_LOG_DEBUG << "Got path: " << path;
174 const std::vector<
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500175 std::pair<std::string, std::vector<std::string>>>&
176 connectionNames = object.second;
Ed Tanous6c34de42018-08-29 13:37:36 -0700177 if (connectionNames.size() < 1)
178 {
179 continue;
180 }
Ed Tanous029573d2019-02-01 10:57:49 -0800181
James Feist5bc2dc82019-10-22 14:33:16 -0700182 auto memoryHealth = std::make_shared<HealthPopulate>(
183 aResp, aResp->res.jsonValue["MemorySummary"]["Status"]);
184
185 auto cpuHealth = std::make_shared<HealthPopulate>(
186 aResp, aResp->res.jsonValue["ProcessorSummary"]["Status"]);
187
188 systemHealth->children.emplace_back(memoryHealth);
189 systemHealth->children.emplace_back(cpuHealth);
190
Ed Tanous029573d2019-02-01 10:57:49 -0800191 // This is not system, so check if it's cpu, dimm, UUID or
192 // BiosVer
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500193 for (const auto& connection : connectionNames)
Ed Tanous6c34de42018-08-29 13:37:36 -0700194 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500195 for (const auto& interfaceName : connection.second)
Ed Tanous6c34de42018-08-29 13:37:36 -0700196 {
Ed Tanous029573d2019-02-01 10:57:49 -0800197 if (interfaceName ==
198 "xyz.openbmc_project.Inventory.Item.Dimm")
Ed Tanous6c34de42018-08-29 13:37:36 -0700199 {
Ed Tanous029573d2019-02-01 10:57:49 -0800200 BMCWEB_LOG_DEBUG
201 << "Found Dimm, now get its properties.";
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500202
Ed Tanous029573d2019-02-01 10:57:49 -0800203 crow::connections::systemBus->async_method_call(
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500204 [aResp, service{connection.first},
Ed Tanousf23b7292020-10-15 09:41:17 -0700205 path](const boost::system::error_code ec2,
206 const std::vector<
207 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},
Ed Tanousf23b7292020-10-15 09:41:17 -0700311 path](const boost::system::error_code ec2,
312 const std::vector<
313 std::pair<std::string, VariantType>>&
314 properties) {
Ed Tanouscb13a392020-07-25 19:02:03 +0000315 if (ec2)
Ed Tanous029573d2019-02-01 10:57:49 -0800316 {
317 BMCWEB_LOG_ERROR
Ed Tanouscb13a392020-07-25 19:02:03 +0000318 << "DBUS response error " << ec2;
Ed Tanous029573d2019-02-01 10:57:49 -0800319 messages::internalError(aResp->res);
320 return;
321 }
322 BMCWEB_LOG_DEBUG << "Got "
323 << properties.size()
Gunnar Mills698654b2019-10-16 13:17:37 -0500324 << " Cpu properties.";
Ed Tanous04a258f2018-10-15 08:00:41 -0700325
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500326 if (properties.size() > 0)
327 {
Zhikui Ren9cf21522020-09-10 11:13:14 -0700328 const uint64_t* processorId = nullptr;
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700329 const std::string* procFamily = nullptr;
330 nlohmann::json& procSummary =
331 aResp->res.jsonValue["ProcessorSumm"
332 "ary"];
333 nlohmann::json& procCount =
334 procSummary["Count"];
335
336 auto procCountPtr = procCount.get_ptr<
337 nlohmann::json::
338 number_integer_t*>();
339 if (procCountPtr == nullptr)
340 {
341 messages::internalError(aResp->res);
342 return;
343 }
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500344 for (const auto& property : properties)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500345 {
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700346
Zhikui Ren9cf21522020-09-10 11:13:14 -0700347 if (property.first == "Id")
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700348 {
349 processorId =
Zhikui Ren9cf21522020-09-10 11:13:14 -0700350 std::get_if<uint64_t>(
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700351 &property.second);
352 if (nullptr != procFamily)
Ed Tanous3174e4d2020-10-07 11:41:22 -0700353 {
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700354 break;
Ed Tanous3174e4d2020-10-07 11:41:22 -0700355 }
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700356 continue;
357 }
358
Zhikui Ren9cf21522020-09-10 11:13:14 -0700359 if (property.first == "Family")
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500360 {
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700361 procFamily =
Patrick Williams8d78b7a2020-05-13 11:24:20 -0500362 std::get_if<std::string>(
363 &property.second);
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700364 if (nullptr != processorId)
Ed Tanous3174e4d2020-10-07 11:41:22 -0700365 {
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700366 break;
Ed Tanous3174e4d2020-10-07 11:41:22 -0700367 }
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700368 continue;
369 }
370 }
James Feistb4b95952019-12-05 15:01:55 -0800371
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700372 if (procFamily != nullptr &&
373 processorId != nullptr)
374 {
375 if (procCountPtr != nullptr &&
376 *processorId != 0)
377 {
378 *procCountPtr += 1;
379 procSummary["Status"]["State"] =
380 "Enabled";
381
382 procSummary["Model"] =
383 *procFamily;
Ed Tanous6c34de42018-08-29 13:37:36 -0700384 }
385 }
Ed Tanous029573d2019-02-01 10:57:49 -0800386 }
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500387 else
388 {
389 auto getCpuPresenceState =
390 [aResp](
391 const boost::system::error_code
Ed Tanouscb13a392020-07-25 19:02:03 +0000392 ec3,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500393 const std::variant<bool>&
394 cpuPresenceCheck) {
Ed Tanouscb13a392020-07-25 19:02:03 +0000395 if (ec3)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500396 {
397 BMCWEB_LOG_ERROR
398 << "DBUS response "
399 "error "
Ed Tanouscb13a392020-07-25 19:02:03 +0000400 << ec3;
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500401 return;
402 }
403 modifyCpuPresenceState(
404 aResp, cpuPresenceCheck);
405 };
406
407 auto getCpuFunctionalState =
408 [aResp](
409 const boost::system::error_code
Ed Tanouscb13a392020-07-25 19:02:03 +0000410 ec3,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500411 const std::variant<bool>&
412 cpuFunctionalCheck) {
Ed Tanouscb13a392020-07-25 19:02:03 +0000413 if (ec3)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500414 {
415 BMCWEB_LOG_ERROR
416 << "DBUS response "
417 "error "
Ed Tanouscb13a392020-07-25 19:02:03 +0000418 << ec3;
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500419 return;
420 }
421 modifyCpuFunctionalState(
422 aResp, cpuFunctionalCheck);
423 };
424 // Get the Presence of CPU
425 crow::connections::systemBus
426 ->async_method_call(
427 std::move(getCpuPresenceState),
428 service, path,
429 "org.freedesktop.DBus."
430 "Properties",
431 "Get",
432 "xyz.openbmc_project.Inventory."
433 "Item",
434 "Present");
435
436 // Get the Functional State
437 crow::connections::systemBus
438 ->async_method_call(
439 std::move(
440 getCpuFunctionalState),
441 service, path,
442 "org.freedesktop.DBus."
443 "Properties",
444 "Get",
445 "xyz.openbmc_project.State."
446 "Decorator."
447 "OperationalStatus",
448 "Functional");
449
450 // Get the MODEL from
451 // xyz.openbmc_project.Inventory.Decorator.Asset
452 // support it later as Model is Empty
453 // currently.
454 }
Ed Tanous029573d2019-02-01 10:57:49 -0800455 },
456 connection.first, path,
457 "org.freedesktop.DBus.Properties", "GetAll",
458 "xyz.openbmc_project.Inventory.Item.Cpu");
James Feist5bc2dc82019-10-22 14:33:16 -0700459
460 cpuHealth->inventory.emplace_back(path);
Ed Tanous029573d2019-02-01 10:57:49 -0800461 }
462 else if (interfaceName ==
463 "xyz.openbmc_project.Common.UUID")
464 {
465 BMCWEB_LOG_DEBUG
466 << "Found UUID, now get its properties.";
467 crow::connections::systemBus->async_method_call(
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500468 [aResp](
Ed Tanouscb13a392020-07-25 19:02:03 +0000469 const boost::system::error_code ec3,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500470 const std::vector<
471 std::pair<std::string, VariantType>>&
472 properties) {
Ed Tanouscb13a392020-07-25 19:02:03 +0000473 if (ec3)
Ed Tanous029573d2019-02-01 10:57:49 -0800474 {
475 BMCWEB_LOG_DEBUG
Ed Tanouscb13a392020-07-25 19:02:03 +0000476 << "DBUS response error " << ec3;
Ed Tanous029573d2019-02-01 10:57:49 -0800477 messages::internalError(aResp->res);
478 return;
479 }
480 BMCWEB_LOG_DEBUG << "Got "
481 << properties.size()
Gunnar Mills698654b2019-10-16 13:17:37 -0500482 << " UUID properties.";
Ed Tanous029573d2019-02-01 10:57:49 -0800483 for (const std::pair<std::string,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500484 VariantType>&
485 property : properties)
Ed Tanous029573d2019-02-01 10:57:49 -0800486 {
Ed Tanous029573d2019-02-01 10:57:49 -0800487 if (property.first == "UUID")
488 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500489 const std::string* value =
Patrick Williams8d78b7a2020-05-13 11:24:20 -0500490 std::get_if<std::string>(
491 &property.second);
Ed Tanous04a258f2018-10-15 08:00:41 -0700492
Ed Tanous029573d2019-02-01 10:57:49 -0800493 if (value != nullptr)
494 {
495 std::string valueStr = *value;
496 if (valueStr.size() == 32)
Ed Tanous6c34de42018-08-29 13:37:36 -0700497 {
Ed Tanous029573d2019-02-01 10:57:49 -0800498 valueStr.insert(8, 1, '-');
499 valueStr.insert(13, 1, '-');
500 valueStr.insert(18, 1, '-');
501 valueStr.insert(23, 1, '-');
Ed Tanous6c34de42018-08-29 13:37:36 -0700502 }
Ed Tanous029573d2019-02-01 10:57:49 -0800503 BMCWEB_LOG_DEBUG << "UUID = "
504 << valueStr;
505 aResp->res.jsonValue["UUID"] =
506 valueStr;
Ed Tanous6c34de42018-08-29 13:37:36 -0700507 }
508 }
Ed Tanous029573d2019-02-01 10:57:49 -0800509 }
510 },
511 connection.first, path,
512 "org.freedesktop.DBus.Properties", "GetAll",
513 "xyz.openbmc_project.Common.UUID");
514 }
515 else if (interfaceName ==
516 "xyz.openbmc_project.Inventory.Item.System")
517 {
518 crow::connections::systemBus->async_method_call(
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500519 [aResp](
Ed Tanouscb13a392020-07-25 19:02:03 +0000520 const boost::system::error_code ec2,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500521 const std::vector<
522 std::pair<std::string, VariantType>>&
523 propertiesList) {
Ed Tanouscb13a392020-07-25 19:02:03 +0000524 if (ec2)
Ed Tanous029573d2019-02-01 10:57:49 -0800525 {
James Feiste4a4b9a2019-06-20 14:08:07 -0700526 // doesn't have to include this
527 // interface
Ed Tanous029573d2019-02-01 10:57:49 -0800528 return;
529 }
Gunnar Mills698654b2019-10-16 13:17:37 -0500530 BMCWEB_LOG_DEBUG
531 << "Got " << propertiesList.size()
532 << " properties for system";
Ed Tanous029573d2019-02-01 10:57:49 -0800533 for (const std::pair<std::string,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500534 VariantType>&
535 property : propertiesList)
Ed Tanous029573d2019-02-01 10:57:49 -0800536 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500537 const std::string& propertyName =
beccabroekfc5afcf2019-03-05 14:35:15 -0600538 property.first;
539 if ((propertyName == "PartNumber") ||
540 (propertyName == "SerialNumber") ||
541 (propertyName == "Manufacturer") ||
542 (propertyName == "Model"))
Ed Tanous029573d2019-02-01 10:57:49 -0800543 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500544 const std::string* value =
beccabroekfc5afcf2019-03-05 14:35:15 -0600545 std::get_if<std::string>(
546 &property.second);
547 if (value != nullptr)
548 {
549 aResp->res
550 .jsonValue[propertyName] =
551 *value;
552 }
Ed Tanous029573d2019-02-01 10:57:49 -0800553 }
554 }
Gunnar Millsc1e236a2020-04-14 21:36:33 -0500555
Andrew Geisslercb7e1e72019-02-19 13:05:38 -0600556 // Grab the bios version
Gunnar Millsf97ddba2020-08-20 15:57:40 -0500557 fw_util::populateFirmwareInformation(
Andrew Geisslercb7e1e72019-02-19 13:05:38 -0600558 aResp, fw_util::biosPurpose,
Gunnar Mills72d566d2020-07-21 12:44:00 -0500559 "BiosVersion", false);
Ed Tanous029573d2019-02-01 10:57:49 -0800560 },
561 connection.first, path,
562 "org.freedesktop.DBus.Properties", "GetAll",
563 "xyz.openbmc_project.Inventory.Decorator."
564 "Asset");
James Feiste4a4b9a2019-06-20 14:08:07 -0700565
566 crow::connections::systemBus->async_method_call(
567 [aResp](
Ed Tanouscb13a392020-07-25 19:02:03 +0000568 const boost::system::error_code ec2,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500569 const std::variant<std::string>& property) {
Ed Tanouscb13a392020-07-25 19:02:03 +0000570 if (ec2)
James Feiste4a4b9a2019-06-20 14:08:07 -0700571 {
572 // doesn't have to include this
573 // interface
574 return;
575 }
576
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500577 const std::string* value =
James Feiste4a4b9a2019-06-20 14:08:07 -0700578 std::get_if<std::string>(&property);
579 if (value != nullptr)
580 {
581 aResp->res.jsonValue["AssetTag"] =
582 *value;
583 }
584 },
585 connection.first, path,
586 "org.freedesktop.DBus.Properties", "Get",
587 "xyz.openbmc_project.Inventory.Decorator."
588 "AssetTag",
589 "AssetTag");
Ed Tanous6c34de42018-08-29 13:37:36 -0700590 }
591 }
592 }
593 }
Ed Tanous6c34de42018-08-29 13:37:36 -0700594 },
595 "xyz.openbmc_project.ObjectMapper",
596 "/xyz/openbmc_project/object_mapper",
597 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
Ed Tanous66173382018-08-15 18:20:59 -0700598 "/xyz/openbmc_project/inventory", int32_t(0),
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500599 std::array<const char*, 5>{
Ed Tanous66173382018-08-15 18:20:59 -0700600 "xyz.openbmc_project.Inventory.Decorator.Asset",
601 "xyz.openbmc_project.Inventory.Item.Cpu",
602 "xyz.openbmc_project.Inventory.Item.Dimm",
603 "xyz.openbmc_project.Inventory.Item.System",
604 "xyz.openbmc_project.Common.UUID",
605 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700606}
607
608/**
Ed Tanous6c34de42018-08-29 13:37:36 -0700609 * @brief Retrieves host state properties over dbus
610 *
611 * @param[in] aResp Shared pointer for completing asynchronous calls.
612 *
613 * @return None.
614 */
Ed Tanousb5a76932020-09-29 16:16:58 -0700615inline void getHostState(const std::shared_ptr<AsyncResp>& aResp)
Ed Tanous6c34de42018-08-29 13:37:36 -0700616{
617 BMCWEB_LOG_DEBUG << "Get host information.";
618 crow::connections::systemBus->async_method_call(
Jennifer Leec5d03ff2019-03-08 15:42:58 -0800619 [aResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500620 const std::variant<std::string>& hostState) {
Ed Tanous6c34de42018-08-29 13:37:36 -0700621 if (ec)
622 {
623 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700624 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700625 return;
626 }
Ed Tanous66173382018-08-15 18:20:59 -0700627
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500628 const std::string* s = std::get_if<std::string>(&hostState);
Ed Tanous66173382018-08-15 18:20:59 -0700629 BMCWEB_LOG_DEBUG << "Host state: " << *s;
630 if (s != nullptr)
Ed Tanous6c34de42018-08-29 13:37:36 -0700631 {
Ed Tanous66173382018-08-15 18:20:59 -0700632 // Verify Host State
Andrew Geissler94732662019-01-08 19:32:16 -0800633 if (*s == "xyz.openbmc_project.State.Host.HostState.Running")
Ed Tanous6c34de42018-08-29 13:37:36 -0700634 {
Ed Tanous66173382018-08-15 18:20:59 -0700635 aResp->res.jsonValue["PowerState"] = "On";
636 aResp->res.jsonValue["Status"]["State"] = "Enabled";
637 }
Andrew Geissler83935af2020-02-13 10:24:53 -0600638 else if (*s == "xyz.openbmc_project.State.Host.HostState."
Gunnar Mills8c888602020-05-01 14:25:09 -0500639 "Quiesced")
640 {
641 aResp->res.jsonValue["PowerState"] = "On";
642 aResp->res.jsonValue["Status"]["State"] = "Quiesced";
643 }
644 else if (*s == "xyz.openbmc_project.State.Host.HostState."
Andrew Geissler83935af2020-02-13 10:24:53 -0600645 "DiagnosticMode")
646 {
647 aResp->res.jsonValue["PowerState"] = "On";
648 aResp->res.jsonValue["Status"]["State"] = "InTest";
649 }
Ed Tanous66173382018-08-15 18:20:59 -0700650 else
651 {
652 aResp->res.jsonValue["PowerState"] = "Off";
653 aResp->res.jsonValue["Status"]["State"] = "Disabled";
Ed Tanous6c34de42018-08-29 13:37:36 -0700654 }
655 }
656 },
657 "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
Ed Tanous66173382018-08-15 18:20:59 -0700658 "org.freedesktop.DBus.Properties", "Get",
659 "xyz.openbmc_project.State.Host", "CurrentHostState");
Ed Tanous6c34de42018-08-29 13:37:36 -0700660}
661
662/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500663 * @brief Translates boot source DBUS property value to redfish.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530664 *
665 * @param[in] dbusSource The boot source in DBUS speak.
666 *
667 * @return Returns as a string, the boot source in Redfish terms. If translation
668 * cannot be done, returns an empty string.
669 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000670inline std::string dbusToRfBootSource(const std::string& dbusSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530671{
672 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
673 {
674 return "None";
675 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700676 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530677 {
678 return "Hdd";
679 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700680 if (dbusSource ==
681 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530682 {
683 return "Cd";
684 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700685 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530686 {
687 return "Pxe";
688 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700689 if (dbusSource ==
690 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700691 {
692 return "Usb";
693 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700694 return "";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530695}
696
697/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500698 * @brief Translates boot mode DBUS property value to redfish.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530699 *
700 * @param[in] dbusMode The boot mode in DBUS speak.
701 *
702 * @return Returns as a string, the boot mode in Redfish terms. If translation
703 * cannot be done, returns an empty string.
704 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000705inline std::string dbusToRfBootMode(const std::string& dbusMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530706{
707 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
708 {
709 return "None";
710 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700711 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530712 {
713 return "Diags";
714 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700715 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530716 {
717 return "BiosSetup";
718 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700719 return "";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530720}
721
722/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500723 * @brief Translates boot source from Redfish to the DBus boot paths.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530724 *
725 * @param[in] rfSource The boot source in Redfish.
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700726 * @param[out] bootSource The DBus source
727 * @param[out] bootMode the DBus boot mode
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530728 *
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700729 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530730 */
Ed Tanousb5a76932020-09-29 16:16:58 -0700731inline int assignBootParameters(const std::shared_ptr<AsyncResp>& aResp,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500732 const std::string& rfSource,
733 std::string& bootSource, std::string& bootMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530734{
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700735 // The caller has initialized the bootSource and bootMode to:
736 // bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
737 // bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
738 // Only modify the bootSource/bootMode variable needed to achieve the
739 // desired boot action.
740
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530741 if (rfSource == "None")
742 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700743 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530744 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700745 if (rfSource == "Pxe")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530746 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700747 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
748 }
749 else if (rfSource == "Hdd")
750 {
751 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
752 }
753 else if (rfSource == "Diags")
754 {
755 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
756 }
757 else if (rfSource == "Cd")
758 {
759 bootSource =
760 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
761 }
762 else if (rfSource == "BiosSetup")
763 {
764 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530765 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700766 else if (rfSource == "Usb")
767 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700768 bootSource =
769 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700770 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530771 else
772 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700773 BMCWEB_LOG_DEBUG << "Invalid property value for "
774 "BootSourceOverrideTarget: "
775 << bootSource;
776 messages::propertyValueNotInList(aResp->res, rfSource,
777 "BootSourceTargetOverride");
778 return -1;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530779 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700780 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530781}
782
783/**
784 * @brief Retrieves boot mode over DBUS and fills out the response
785 *
786 * @param[in] aResp Shared pointer for generating response message.
787 * @param[in] bootDbusObj The dbus object to query for boot properties.
788 *
789 * @return None.
790 */
Ed Tanousb5a76932020-09-29 16:16:58 -0700791inline void getBootMode(const std::shared_ptr<AsyncResp>& aResp,
792 const std::string& bootDbusObj)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530793{
794 crow::connections::systemBus->async_method_call(
795 [aResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500796 const std::variant<std::string>& bootMode) {
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530797 if (ec)
798 {
799 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
800 messages::internalError(aResp->res);
801 return;
802 }
803
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500804 const std::string* bootModeStr =
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530805 std::get_if<std::string>(&bootMode);
806
807 if (!bootModeStr)
808 {
809 messages::internalError(aResp->res);
810 return;
811 }
812
813 BMCWEB_LOG_DEBUG << "Boot mode: " << *bootModeStr;
814
815 // TODO (Santosh): Do we need to support override mode?
816 aResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = "Legacy";
817 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget@Redfish."
818 "AllowableValues"] = {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700819 "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530820
821 if (*bootModeStr !=
822 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
823 {
824 auto rfMode = dbusToRfBootMode(*bootModeStr);
825 if (!rfMode.empty())
826 {
827 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
828 rfMode;
829 }
830 }
831
832 // If the BootSourceOverrideTarget is still "None" at the end,
833 // reset the BootSourceOverrideEnabled to indicate that
834 // overrides are disabled
835 if (aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] ==
836 "None")
837 {
838 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
839 "Disabled";
840 }
841 },
842 "xyz.openbmc_project.Settings", bootDbusObj,
843 "org.freedesktop.DBus.Properties", "Get",
844 "xyz.openbmc_project.Control.Boot.Mode", "BootMode");
845}
846
847/**
848 * @brief Retrieves boot source over DBUS
849 *
850 * @param[in] aResp Shared pointer for generating response message.
851 * @param[in] oneTimeEnable Boolean to indicate boot properties are one-time.
852 *
853 * @return None.
854 */
Ed Tanousf23b7292020-10-15 09:41:17 -0700855inline void getBootSource(const std::shared_ptr<AsyncResp>& aResp,
856 bool oneTimeEnabled)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530857{
858 std::string bootDbusObj =
859 oneTimeEnabled ? "/xyz/openbmc_project/control/host0/boot/one_time"
860 : "/xyz/openbmc_project/control/host0/boot";
861
862 BMCWEB_LOG_DEBUG << "Is one time: " << oneTimeEnabled;
863 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
864 (oneTimeEnabled) ? "Once" : "Continuous";
865
866 crow::connections::systemBus->async_method_call(
867 [aResp, bootDbusObj](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500868 const std::variant<std::string>& bootSource) {
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530869 if (ec)
870 {
871 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
872 messages::internalError(aResp->res);
873 return;
874 }
875
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500876 const std::string* bootSourceStr =
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530877 std::get_if<std::string>(&bootSource);
878
879 if (!bootSourceStr)
880 {
881 messages::internalError(aResp->res);
882 return;
883 }
884 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSourceStr;
885
886 auto rfSource = dbusToRfBootSource(*bootSourceStr);
887 if (!rfSource.empty())
888 {
889 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
890 rfSource;
891 }
892 },
893 "xyz.openbmc_project.Settings", bootDbusObj,
894 "org.freedesktop.DBus.Properties", "Get",
895 "xyz.openbmc_project.Control.Boot.Source", "BootSource");
Ed Tanousf23b7292020-10-15 09:41:17 -0700896 getBootMode(aResp, bootDbusObj);
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530897}
898
899/**
900 * @brief Retrieves "One time" enabled setting over DBUS and calls function to
901 * get boot source and boot mode.
902 *
903 * @param[in] aResp Shared pointer for generating response message.
904 *
905 * @return None.
906 */
Ed Tanousb5a76932020-09-29 16:16:58 -0700907inline void getBootProperties(const std::shared_ptr<AsyncResp>& aResp)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530908{
909 BMCWEB_LOG_DEBUG << "Get boot information.";
910
911 crow::connections::systemBus->async_method_call(
Jennifer Leec5d03ff2019-03-08 15:42:58 -0800912 [aResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500913 const std::variant<bool>& oneTime) {
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530914 if (ec)
915 {
916 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
James Feist2a833c72019-07-19 10:17:13 -0700917 // not an error, don't have to have the interface
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530918 return;
919 }
920
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500921 const bool* oneTimePtr = std::get_if<bool>(&oneTime);
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530922
923 if (!oneTimePtr)
924 {
925 messages::internalError(aResp->res);
926 return;
927 }
928 getBootSource(aResp, *oneTimePtr);
929 },
930 "xyz.openbmc_project.Settings",
931 "/xyz/openbmc_project/control/host0/boot/one_time",
932 "org.freedesktop.DBus.Properties", "Get",
933 "xyz.openbmc_project.Object.Enable", "Enabled");
934}
935
936/**
Gunnar Millsc0557e12020-06-30 11:26:20 -0500937 * @brief Retrieves the Last Reset Time
938 *
939 * "Reset" is an overloaded term in Redfish, "Reset" includes power on
940 * and power off. Even though this is the "system" Redfish object look at the
941 * chassis D-Bus interface for the LastStateChangeTime since this has the
942 * last power operation time.
943 *
944 * @param[in] aResp Shared pointer for generating response message.
945 *
946 * @return None.
947 */
Ed Tanousb5a76932020-09-29 16:16:58 -0700948inline void getLastResetTime(const std::shared_ptr<AsyncResp>& aResp)
Gunnar Millsc0557e12020-06-30 11:26:20 -0500949{
950 BMCWEB_LOG_DEBUG << "Getting System Last Reset Time";
951
952 crow::connections::systemBus->async_method_call(
953 [aResp](const boost::system::error_code ec,
954 std::variant<uint64_t>& lastResetTime) {
955 if (ec)
956 {
957 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
958 return;
959 }
960
961 const uint64_t* lastResetTimePtr =
962 std::get_if<uint64_t>(&lastResetTime);
963
964 if (!lastResetTimePtr)
965 {
966 messages::internalError(aResp->res);
967 return;
968 }
969 // LastStateChangeTime is epoch time, in milliseconds
970 // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
971 time_t lastResetTimeStamp =
972 static_cast<time_t>(*lastResetTimePtr / 1000);
973
974 // Convert to ISO 8601 standard
975 aResp->res.jsonValue["LastResetTime"] =
976 crow::utility::getDateTime(lastResetTimeStamp);
977 },
978 "xyz.openbmc_project.State.Chassis",
979 "/xyz/openbmc_project/state/chassis0",
980 "org.freedesktop.DBus.Properties", "Get",
981 "xyz.openbmc_project.State.Chassis", "LastStateChangeTime");
982}
983
984/**
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -0500985 * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
986 *
987 * @param[in] aResp Shared pointer for generating response message.
988 *
989 * @return None.
990 */
Ed Tanousb5a76932020-09-29 16:16:58 -0700991inline void getAutomaticRetry(const std::shared_ptr<AsyncResp>& aResp)
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -0500992{
993 BMCWEB_LOG_DEBUG << "Get Automatic Retry policy";
994
995 crow::connections::systemBus->async_method_call(
996 [aResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500997 std::variant<bool>& autoRebootEnabled) {
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -0500998 if (ec)
999 {
1000 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
1001 return;
1002 }
1003
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001004 const bool* autoRebootEnabledPtr =
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001005 std::get_if<bool>(&autoRebootEnabled);
1006
1007 if (!autoRebootEnabledPtr)
1008 {
1009 messages::internalError(aResp->res);
1010 return;
1011 }
1012
1013 BMCWEB_LOG_DEBUG << "Auto Reboot: " << *autoRebootEnabledPtr;
1014 if (*autoRebootEnabledPtr == true)
1015 {
1016 aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
1017 "RetryAttempts";
1018 // If AutomaticRetry (AutoReboot) is enabled see how many
1019 // attempts are left
1020 crow::connections::systemBus->async_method_call(
Ed Tanouscb13a392020-07-25 19:02:03 +00001021 [aResp](const boost::system::error_code ec2,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001022 std::variant<uint32_t>& autoRebootAttemptsLeft) {
Ed Tanouscb13a392020-07-25 19:02:03 +00001023 if (ec2)
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001024 {
Ed Tanouscb13a392020-07-25 19:02:03 +00001025 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec2;
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001026 return;
1027 }
1028
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001029 const uint32_t* autoRebootAttemptsLeftPtr =
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001030 std::get_if<uint32_t>(&autoRebootAttemptsLeft);
1031
1032 if (!autoRebootAttemptsLeftPtr)
1033 {
1034 messages::internalError(aResp->res);
1035 return;
1036 }
1037
1038 BMCWEB_LOG_DEBUG << "Auto Reboot Attempts Left: "
1039 << *autoRebootAttemptsLeftPtr;
1040
1041 aResp->res
1042 .jsonValue["Boot"]
1043 ["RemainingAutomaticRetryAttempts"] =
1044 *autoRebootAttemptsLeftPtr;
1045 },
1046 "xyz.openbmc_project.State.Host",
1047 "/xyz/openbmc_project/state/host0",
1048 "org.freedesktop.DBus.Properties", "Get",
1049 "xyz.openbmc_project.Control.Boot.RebootAttempts",
1050 "AttemptsLeft");
1051 }
1052 else
1053 {
1054 aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
1055 "Disabled";
1056 }
1057
1058 // Not on D-Bus. Hardcoded here:
1059 // https://github.com/openbmc/phosphor-state-manager/blob/1dbbef42675e94fb1f78edb87d6b11380260535a/meson_options.txt#L71
1060 aResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] = 3;
Gunnar Mills69f35302020-05-17 16:06:31 -05001061
1062 // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
1063 // and RetryAttempts. OpenBMC only supports Disabled and
1064 // RetryAttempts.
1065 aResp->res.jsonValue["Boot"]["AutomaticRetryConfig@Redfish."
1066 "AllowableValues"] = {"Disabled",
1067 "RetryAttempts"};
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001068 },
1069 "xyz.openbmc_project.Settings",
1070 "/xyz/openbmc_project/control/host0/auto_reboot",
1071 "org.freedesktop.DBus.Properties", "Get",
1072 "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot");
1073}
1074
1075/**
George Liuc6a620f2020-04-10 17:18:11 +08001076 * @brief Retrieves power restore policy over DBUS.
1077 *
1078 * @param[in] aResp Shared pointer for generating response message.
1079 *
1080 * @return None.
1081 */
Ed Tanousb5a76932020-09-29 16:16:58 -07001082inline void getPowerRestorePolicy(const std::shared_ptr<AsyncResp>& aResp)
George Liuc6a620f2020-04-10 17:18:11 +08001083{
1084 BMCWEB_LOG_DEBUG << "Get power restore policy";
1085
1086 crow::connections::systemBus->async_method_call(
1087 [aResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001088 std::variant<std::string>& policy) {
George Liuc6a620f2020-04-10 17:18:11 +08001089 if (ec)
1090 {
1091 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1092 return;
1093 }
1094
1095 const boost::container::flat_map<std::string, std::string>
1096 policyMaps = {
1097 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1098 "AlwaysOn",
1099 "AlwaysOn"},
1100 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1101 "AlwaysOff",
1102 "AlwaysOff"},
1103 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1104 "LastState",
1105 "LastState"}};
1106
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001107 const std::string* policyPtr = std::get_if<std::string>(&policy);
George Liuc6a620f2020-04-10 17:18:11 +08001108
1109 if (!policyPtr)
1110 {
1111 messages::internalError(aResp->res);
1112 return;
1113 }
1114
1115 auto policyMapsIt = policyMaps.find(*policyPtr);
1116 if (policyMapsIt == policyMaps.end())
1117 {
1118 messages::internalError(aResp->res);
1119 return;
1120 }
1121
1122 aResp->res.jsonValue["PowerRestorePolicy"] = policyMapsIt->second;
1123 },
1124 "xyz.openbmc_project.Settings",
1125 "/xyz/openbmc_project/control/host0/power_restore_policy",
1126 "org.freedesktop.DBus.Properties", "Get",
1127 "xyz.openbmc_project.Control.Power.RestorePolicy",
1128 "PowerRestorePolicy");
1129}
1130
1131/**
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301132 * @brief Sets boot properties into DBUS object(s).
1133 *
1134 * @param[in] aResp Shared pointer for generating response message.
1135 * @param[in] oneTimeEnabled Is "one-time" setting already enabled.
1136 * @param[in] bootSource The boot source to set.
1137 * @param[in] bootEnable The source override "enable" to set.
1138 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001139 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301140 */
Ed Tanous23a21a12020-07-25 04:45:05 +00001141inline void setBootModeOrSource(std::shared_ptr<AsyncResp> aResp,
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301142 bool oneTimeEnabled,
Ed Tanousf23b7292020-10-15 09:41:17 -07001143 const std::optional<std::string>& bootSource,
1144 const std::optional<std::string>& bootEnable)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301145{
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001146 std::string bootSourceStr =
1147 "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
1148 std::string bootModeStr =
1149 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301150 bool oneTimeSetting = oneTimeEnabled;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001151 bool useBootSource = true;
1152
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301153 // Validate incoming parameters
1154 if (bootEnable)
1155 {
1156 if (*bootEnable == "Once")
1157 {
1158 oneTimeSetting = true;
1159 }
1160 else if (*bootEnable == "Continuous")
1161 {
1162 oneTimeSetting = false;
1163 }
1164 else if (*bootEnable == "Disabled")
1165 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001166 BMCWEB_LOG_DEBUG << "Boot source override will be disabled";
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301167 oneTimeSetting = false;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001168 useBootSource = false;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301169 }
1170 else
1171 {
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301172 BMCWEB_LOG_DEBUG << "Unsupported value for "
1173 "BootSourceOverrideEnabled: "
1174 << *bootEnable;
1175 messages::propertyValueNotInList(aResp->res, *bootEnable,
1176 "BootSourceOverrideEnabled");
1177 return;
1178 }
1179 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301180
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001181 if (bootSource && useBootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301182 {
1183 // Source target specified
1184 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource;
1185 // Figure out which DBUS interface and property to use
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001186 if (assignBootParameters(aResp, *bootSource, bootSourceStr,
1187 bootModeStr))
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301188 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001189 BMCWEB_LOG_DEBUG
1190 << "Invalid property value for BootSourceOverrideTarget: "
1191 << *bootSource;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301192 messages::propertyValueNotInList(aResp->res, *bootSource,
1193 "BootSourceTargetOverride");
1194 return;
1195 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001196 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301197
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001198 // Act on validated parameters
1199 BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
1200 BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001201 const char* bootObj =
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001202 oneTimeSetting ? "/xyz/openbmc_project/control/host0/boot/one_time"
1203 : "/xyz/openbmc_project/control/host0/boot";
1204
1205 crow::connections::systemBus->async_method_call(
1206 [aResp](const boost::system::error_code ec) {
1207 if (ec)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301208 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001209 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1210 messages::internalError(aResp->res);
1211 return;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301212 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001213 BMCWEB_LOG_DEBUG << "Boot source update done.";
1214 },
1215 "xyz.openbmc_project.Settings", bootObj,
1216 "org.freedesktop.DBus.Properties", "Set",
1217 "xyz.openbmc_project.Control.Boot.Source", "BootSource",
1218 std::variant<std::string>(bootSourceStr));
1219
1220 crow::connections::systemBus->async_method_call(
1221 [aResp](const boost::system::error_code ec) {
1222 if (ec)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301223 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001224 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1225 messages::internalError(aResp->res);
1226 return;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301227 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001228 BMCWEB_LOG_DEBUG << "Boot mode update done.";
1229 },
1230 "xyz.openbmc_project.Settings", bootObj,
1231 "org.freedesktop.DBus.Properties", "Set",
1232 "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
1233 std::variant<std::string>(bootModeStr));
1234
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301235 crow::connections::systemBus->async_method_call(
1236 [aResp{std::move(aResp)}](const boost::system::error_code ec) {
1237 if (ec)
1238 {
1239 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1240 messages::internalError(aResp->res);
1241 return;
1242 }
1243 BMCWEB_LOG_DEBUG << "Boot enable update done.";
1244 },
1245 "xyz.openbmc_project.Settings",
1246 "/xyz/openbmc_project/control/host0/boot/one_time",
1247 "org.freedesktop.DBus.Properties", "Set",
1248 "xyz.openbmc_project.Object.Enable", "Enabled",
1249 std::variant<bool>(oneTimeSetting));
1250}
1251
1252/**
1253 * @brief Retrieves "One time" enabled setting over DBUS and calls function to
1254 * set boot source/boot mode properties.
1255 *
1256 * @param[in] aResp Shared pointer for generating response message.
1257 * @param[in] bootSource The boot source from incoming RF request.
1258 * @param[in] bootEnable The boot override enable from incoming RF request.
1259 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001260 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301261 */
Ed Tanousb5a76932020-09-29 16:16:58 -07001262inline void setBootSourceProperties(const std::shared_ptr<AsyncResp>& aResp,
Gunnar Mills69f35302020-05-17 16:06:31 -05001263 std::optional<std::string> bootSource,
1264 std::optional<std::string> bootEnable)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301265{
1266 BMCWEB_LOG_DEBUG << "Set boot information.";
1267
1268 crow::connections::systemBus->async_method_call(
Johnathan Mantey265c1602019-08-08 11:02:51 -07001269 [aResp, bootSource{std::move(bootSource)},
Patrick Williams19bd78d2020-05-13 17:38:24 -05001270 bootEnable{std::move(bootEnable)}](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001271 const std::variant<bool>& oneTime) {
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301272 if (ec)
1273 {
1274 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1275 messages::internalError(aResp->res);
1276 return;
1277 }
1278
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001279 const bool* oneTimePtr = std::get_if<bool>(&oneTime);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301280
1281 if (!oneTimePtr)
1282 {
1283 messages::internalError(aResp->res);
1284 return;
1285 }
1286
1287 BMCWEB_LOG_DEBUG << "Got one time: " << *oneTimePtr;
1288
Ed Tanousf23b7292020-10-15 09:41:17 -07001289 setBootModeOrSource(aResp, *oneTimePtr, bootSource, bootEnable);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301290 },
1291 "xyz.openbmc_project.Settings",
1292 "/xyz/openbmc_project/control/host0/boot/one_time",
1293 "org.freedesktop.DBus.Properties", "Get",
1294 "xyz.openbmc_project.Object.Enable", "Enabled");
1295}
1296
George Liuc6a620f2020-04-10 17:18:11 +08001297/**
Gunnar Mills69f35302020-05-17 16:06:31 -05001298 * @brief Sets automaticRetry (Auto Reboot)
1299 *
1300 * @param[in] aResp Shared pointer for generating response message.
1301 * @param[in] automaticRetryConfig "AutomaticRetryConfig" from request.
1302 *
1303 * @return None.
1304 */
Ed Tanousb5a76932020-09-29 16:16:58 -07001305inline void setAutomaticRetry(const std::shared_ptr<AsyncResp>& aResp,
Ed Tanousf23b7292020-10-15 09:41:17 -07001306 const std::string& automaticRetryConfig)
Gunnar Mills69f35302020-05-17 16:06:31 -05001307{
1308 BMCWEB_LOG_DEBUG << "Set Automatic Retry.";
1309
1310 // OpenBMC only supports "Disabled" and "RetryAttempts".
1311 bool autoRebootEnabled;
1312
1313 if (automaticRetryConfig == "Disabled")
1314 {
1315 autoRebootEnabled = false;
1316 }
1317 else if (automaticRetryConfig == "RetryAttempts")
1318 {
1319 autoRebootEnabled = true;
1320 }
1321 else
1322 {
1323 BMCWEB_LOG_DEBUG << "Invalid property value for "
1324 "AutomaticRetryConfig: "
1325 << automaticRetryConfig;
1326 messages::propertyValueNotInList(aResp->res, automaticRetryConfig,
1327 "AutomaticRetryConfig");
1328 return;
1329 }
1330
1331 crow::connections::systemBus->async_method_call(
1332 [aResp](const boost::system::error_code ec) {
1333 if (ec)
1334 {
1335 messages::internalError(aResp->res);
1336 return;
1337 }
1338 },
1339 "xyz.openbmc_project.Settings",
1340 "/xyz/openbmc_project/control/host0/auto_reboot",
1341 "org.freedesktop.DBus.Properties", "Set",
1342 "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
1343 std::variant<bool>(autoRebootEnabled));
1344}
1345
1346/**
George Liuc6a620f2020-04-10 17:18:11 +08001347 * @brief Sets power restore policy properties.
1348 *
1349 * @param[in] aResp Shared pointer for generating response message.
1350 * @param[in] policy power restore policy properties from request.
1351 *
1352 * @return None.
1353 */
Ed Tanousb5a76932020-09-29 16:16:58 -07001354inline void setPowerRestorePolicy(const std::shared_ptr<AsyncResp>& aResp,
George Liuc6a620f2020-04-10 17:18:11 +08001355 std::optional<std::string> policy)
1356{
1357 BMCWEB_LOG_DEBUG << "Set power restore policy.";
1358
1359 const boost::container::flat_map<std::string, std::string> policyMaps = {
1360 {"AlwaysOn", "xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1361 "AlwaysOn"},
1362 {"AlwaysOff", "xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1363 "AlwaysOff"},
1364 {"LastState", "xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1365 "LastState"}};
1366
1367 std::string powerRestorPolicy;
1368
1369 auto policyMapsIt = policyMaps.find(*policy);
1370 if (policyMapsIt == policyMaps.end())
1371 {
1372 messages::internalError(aResp->res);
1373 return;
1374 }
1375
1376 powerRestorPolicy = policyMapsIt->second;
1377
1378 crow::connections::systemBus->async_method_call(
1379 [aResp](const boost::system::error_code ec) {
1380 if (ec)
1381 {
1382 messages::internalError(aResp->res);
1383 return;
1384 }
1385 },
1386 "xyz.openbmc_project.Settings",
1387 "/xyz/openbmc_project/control/host0/power_restore_policy",
1388 "org.freedesktop.DBus.Properties", "Set",
1389 "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
1390 std::variant<std::string>(powerRestorPolicy));
1391}
1392
AppaRao Pulia6349912019-10-18 17:16:08 +05301393#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1394/**
1395 * @brief Retrieves provisioning status
1396 *
1397 * @param[in] aResp Shared pointer for completing asynchronous calls.
1398 *
1399 * @return None.
1400 */
Ed Tanous23a21a12020-07-25 04:45:05 +00001401inline void getProvisioningStatus(std::shared_ptr<AsyncResp> aResp)
AppaRao Pulia6349912019-10-18 17:16:08 +05301402{
1403 BMCWEB_LOG_DEBUG << "Get OEM information.";
1404 crow::connections::systemBus->async_method_call(
1405 [aResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001406 const std::vector<std::pair<std::string, VariantType>>&
1407 propertiesList) {
AppaRao Pulib99fb1a2020-07-08 16:42:48 +05301408 nlohmann::json& oemPFR =
1409 aResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
James Feist50626f42020-09-23 14:40:47 -07001410 aResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
1411 "#OemComputerSystem.OpenBmc";
1412 oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning";
1413
AppaRao Pulia6349912019-10-18 17:16:08 +05301414 if (ec)
1415 {
1416 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
AppaRao Pulib99fb1a2020-07-08 16:42:48 +05301417 // not an error, don't have to have the interface
1418 oemPFR["ProvisioningStatus"] = "NotProvisioned";
AppaRao Pulia6349912019-10-18 17:16:08 +05301419 return;
1420 }
1421
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001422 const bool* provState = nullptr;
1423 const bool* lockState = nullptr;
1424 for (const std::pair<std::string, VariantType>& property :
AppaRao Pulia6349912019-10-18 17:16:08 +05301425 propertiesList)
1426 {
1427 if (property.first == "UfmProvisioned")
1428 {
1429 provState = std::get_if<bool>(&property.second);
1430 }
1431 else if (property.first == "UfmLocked")
1432 {
1433 lockState = std::get_if<bool>(&property.second);
1434 }
1435 }
1436
1437 if ((provState == nullptr) || (lockState == nullptr))
1438 {
1439 BMCWEB_LOG_DEBUG << "Unable to get PFR attributes.";
1440 messages::internalError(aResp->res);
1441 return;
1442 }
1443
AppaRao Pulia6349912019-10-18 17:16:08 +05301444 if (*provState == true)
1445 {
1446 if (*lockState == true)
1447 {
1448 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
1449 }
1450 else
1451 {
1452 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
1453 }
1454 }
1455 else
1456 {
1457 oemPFR["ProvisioningStatus"] = "NotProvisioned";
1458 }
1459 },
1460 "xyz.openbmc_project.PFR.Manager", "/xyz/openbmc_project/pfr",
1461 "org.freedesktop.DBus.Properties", "GetAll",
1462 "xyz.openbmc_project.PFR.Attributes");
1463}
1464#endif
1465
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301466/**
Yong Li51709ff2019-09-30 14:13:04 +08001467 * @brief Translates watchdog timeout action DBUS property value to redfish.
1468 *
1469 * @param[in] dbusAction The watchdog timeout action in D-BUS.
1470 *
1471 * @return Returns as a string, the timeout action in Redfish terms. If
1472 * translation cannot be done, returns an empty string.
1473 */
Ed Tanous23a21a12020-07-25 04:45:05 +00001474inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
Yong Li51709ff2019-09-30 14:13:04 +08001475{
1476 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
1477 {
1478 return "None";
1479 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07001480 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
Yong Li51709ff2019-09-30 14:13:04 +08001481 {
1482 return "ResetSystem";
1483 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07001484 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
Yong Li51709ff2019-09-30 14:13:04 +08001485 {
1486 return "PowerDown";
1487 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07001488 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
Yong Li51709ff2019-09-30 14:13:04 +08001489 {
1490 return "PowerCycle";
1491 }
1492
1493 return "";
1494}
1495
1496/**
Yong Lic45f0082019-10-10 14:19:01 +08001497 *@brief Translates timeout action from Redfish to DBUS property value.
1498 *
1499 *@param[in] rfAction The timeout action in Redfish.
1500 *
1501 *@return Returns as a string, the time_out action as expected by DBUS.
1502 *If translation cannot be done, returns an empty string.
1503 */
1504
Ed Tanous23a21a12020-07-25 04:45:05 +00001505inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
Yong Lic45f0082019-10-10 14:19:01 +08001506{
1507 if (rfAction == "None")
1508 {
1509 return "xyz.openbmc_project.State.Watchdog.Action.None";
1510 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07001511 if (rfAction == "PowerCycle")
Yong Lic45f0082019-10-10 14:19:01 +08001512 {
1513 return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
1514 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07001515 if (rfAction == "PowerDown")
Yong Lic45f0082019-10-10 14:19:01 +08001516 {
1517 return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
1518 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07001519 if (rfAction == "ResetSystem")
Yong Lic45f0082019-10-10 14:19:01 +08001520 {
1521 return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
1522 }
1523
1524 return "";
1525}
1526
1527/**
Yong Li51709ff2019-09-30 14:13:04 +08001528 * @brief Retrieves host watchdog timer properties over DBUS
1529 *
1530 * @param[in] aResp Shared pointer for completing asynchronous calls.
1531 *
1532 * @return None.
1533 */
Ed Tanousb5a76932020-09-29 16:16:58 -07001534inline void getHostWatchdogTimer(const std::shared_ptr<AsyncResp>& aResp)
Yong Li51709ff2019-09-30 14:13:04 +08001535{
1536 BMCWEB_LOG_DEBUG << "Get host watchodg";
1537 crow::connections::systemBus->async_method_call(
1538 [aResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001539 PropertiesType& properties) {
Yong Li51709ff2019-09-30 14:13:04 +08001540 if (ec)
1541 {
1542 // watchdog service is stopped
1543 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1544 return;
1545 }
1546
1547 BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop.";
1548
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001549 nlohmann::json& hostWatchdogTimer =
Yong Li51709ff2019-09-30 14:13:04 +08001550 aResp->res.jsonValue["HostWatchdogTimer"];
1551
1552 // watchdog service is running/enabled
1553 hostWatchdogTimer["Status"]["State"] = "Enabled";
1554
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001555 for (const auto& property : properties)
Yong Li51709ff2019-09-30 14:13:04 +08001556 {
1557 BMCWEB_LOG_DEBUG << "prop=" << property.first;
1558 if (property.first == "Enabled")
1559 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001560 const bool* state = std::get_if<bool>(&property.second);
Yong Li51709ff2019-09-30 14:13:04 +08001561
1562 if (!state)
1563 {
1564 messages::internalError(aResp->res);
1565 continue;
1566 }
1567
1568 hostWatchdogTimer["FunctionEnabled"] = *state;
1569 }
1570 else if (property.first == "ExpireAction")
1571 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001572 const std::string* s =
Yong Li51709ff2019-09-30 14:13:04 +08001573 std::get_if<std::string>(&property.second);
1574 if (!s)
1575 {
1576 messages::internalError(aResp->res);
1577 continue;
1578 }
1579
1580 std::string action = dbusToRfWatchdogAction(*s);
1581 if (action.empty())
1582 {
1583 messages::internalError(aResp->res);
1584 continue;
1585 }
1586 hostWatchdogTimer["TimeoutAction"] = action;
1587 }
1588 }
1589 },
1590 "xyz.openbmc_project.Watchdog", "/xyz/openbmc_project/watchdog/host0",
1591 "org.freedesktop.DBus.Properties", "GetAll",
1592 "xyz.openbmc_project.State.Watchdog");
1593}
1594
1595/**
Yong Lic45f0082019-10-10 14:19:01 +08001596 * @brief Sets Host WatchDog Timer properties.
1597 *
1598 * @param[in] aResp Shared pointer for generating response message.
1599 * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming
1600 * RF request.
1601 * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
1602 *
1603 * @return None.
1604 */
Ed Tanousb5a76932020-09-29 16:16:58 -07001605inline void setWDTProperties(const std::shared_ptr<AsyncResp>& aResp,
Yong Lic45f0082019-10-10 14:19:01 +08001606 const std::optional<bool> wdtEnable,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001607 const std::optional<std::string>& wdtTimeOutAction)
Yong Lic45f0082019-10-10 14:19:01 +08001608{
1609 BMCWEB_LOG_DEBUG << "Set host watchdog";
1610
1611 if (wdtTimeOutAction)
1612 {
1613 std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
1614 // check if TimeOut Action is Valid
1615 if (wdtTimeOutActStr.empty())
1616 {
1617 BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: "
1618 << *wdtTimeOutAction;
1619 messages::propertyValueNotInList(aResp->res, *wdtTimeOutAction,
1620 "TimeoutAction");
1621 return;
1622 }
1623
1624 crow::connections::systemBus->async_method_call(
1625 [aResp](const boost::system::error_code ec) {
1626 if (ec)
1627 {
1628 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1629 messages::internalError(aResp->res);
1630 return;
1631 }
1632 },
1633 "xyz.openbmc_project.Watchdog",
1634 "/xyz/openbmc_project/watchdog/host0",
1635 "org.freedesktop.DBus.Properties", "Set",
1636 "xyz.openbmc_project.State.Watchdog", "ExpireAction",
1637 std::variant<std::string>(wdtTimeOutActStr));
1638 }
1639
1640 if (wdtEnable)
1641 {
1642 crow::connections::systemBus->async_method_call(
1643 [aResp](const boost::system::error_code ec) {
1644 if (ec)
1645 {
1646 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1647 messages::internalError(aResp->res);
1648 return;
1649 }
1650 },
1651 "xyz.openbmc_project.Watchdog",
1652 "/xyz/openbmc_project/watchdog/host0",
1653 "org.freedesktop.DBus.Properties", "Set",
1654 "xyz.openbmc_project.State.Watchdog", "Enabled",
1655 std::variant<bool>(*wdtEnable));
1656 }
1657}
1658
1659/**
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001660 * SystemsCollection derived class for delivering ComputerSystems Collection
1661 * Schema
1662 */
Ed Tanous1abe55e2018-09-05 08:30:59 -07001663class SystemsCollection : public Node
1664{
1665 public:
Ed Tanous52cc1122020-07-18 13:51:21 -07001666 SystemsCollection(App& app) : Node(app, "/redfish/v1/Systems/")
Ed Tanous1abe55e2018-09-05 08:30:59 -07001667 {
Ed Tanous1abe55e2018-09-05 08:30:59 -07001668 entityPrivileges = {
1669 {boost::beast::http::verb::get, {{"Login"}}},
1670 {boost::beast::http::verb::head, {{"Login"}}},
1671 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1672 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1673 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1674 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1675 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001676
Ed Tanous1abe55e2018-09-05 08:30:59 -07001677 private:
Ed Tanouscb13a392020-07-25 19:02:03 +00001678 void doGet(crow::Response& res, const crow::Request&,
1679 const std::vector<std::string>&) override
Ed Tanous1abe55e2018-09-05 08:30:59 -07001680 {
Sunitha Harish462023a2020-02-19 08:34:59 -06001681 std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
Ed Tanous0f74e642018-11-12 15:17:05 -08001682 res.jsonValue["@odata.type"] =
1683 "#ComputerSystemCollection.ComputerSystemCollection";
1684 res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
Ed Tanous0f74e642018-11-12 15:17:05 -08001685 res.jsonValue["Name"] = "Computer System Collection";
Sunitha Harish462023a2020-02-19 08:34:59 -06001686
1687 crow::connections::systemBus->async_method_call(
1688 [asyncResp](const boost::system::error_code ec,
Ed Tanouscb13a392020-07-25 19:02:03 +00001689 const std::variant<std::string>& /*hostName*/) {
Ed Tanous2c70f802020-09-28 14:29:23 -07001690 nlohmann::json& ifaceArray =
Sunitha Harish462023a2020-02-19 08:34:59 -06001691 asyncResp->res.jsonValue["Members"];
Ed Tanous2c70f802020-09-28 14:29:23 -07001692 ifaceArray = nlohmann::json::array();
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001693 auto& count = asyncResp->res.jsonValue["Members@odata.count"];
Sunitha Harish462023a2020-02-19 08:34:59 -06001694 count = 0;
Ed Tanous2c70f802020-09-28 14:29:23 -07001695 ifaceArray.push_back(
Ed Tanouscb13a392020-07-25 19:02:03 +00001696 {{"@odata.id", "/redfish/v1/Systems/system"}});
1697 if (!ec)
Sunitha Harish462023a2020-02-19 08:34:59 -06001698 {
Ed Tanouscb13a392020-07-25 19:02:03 +00001699 BMCWEB_LOG_DEBUG << "Hypervisor is available";
Ed Tanous2c70f802020-09-28 14:29:23 -07001700 ifaceArray.push_back(
Ed Tanouscb13a392020-07-25 19:02:03 +00001701 {{"@odata.id", "/redfish/v1/Systems/hypervisor"}});
Ed Tanous2c70f802020-09-28 14:29:23 -07001702 count = ifaceArray.size();
Sunitha Harish462023a2020-02-19 08:34:59 -06001703 return;
1704 }
Sunitha Harish462023a2020-02-19 08:34:59 -06001705 },
Sunitha Harish8e651fb2020-06-17 06:06:25 -05001706 "xyz.openbmc_project.Settings",
1707 "/xyz/openbmc_project/network/hypervisor",
Sunitha Harish462023a2020-02-19 08:34:59 -06001708 "org.freedesktop.DBus.Properties", "Get",
1709 "xyz.openbmc_project.Network.SystemConfiguration", "HostName");
Ed Tanous1abe55e2018-09-05 08:30:59 -07001710 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001711};
1712
1713/**
Ed Tanouscc340dd2018-08-29 13:43:38 -07001714 * SystemActionsReset class supports handle POST method for Reset action.
1715 * The class retrieves and sends data directly to D-Bus.
1716 */
1717class SystemActionsReset : public Node
1718{
1719 public:
Ed Tanous52cc1122020-07-18 13:51:21 -07001720 SystemActionsReset(App& app) :
Ed Tanous029573d2019-02-01 10:57:49 -08001721 Node(app, "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/")
Ed Tanouscc340dd2018-08-29 13:43:38 -07001722 {
1723 entityPrivileges = {
1724 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1725 }
1726
1727 private:
1728 /**
1729 * Function handles POST method request.
1730 * Analyzes POST body message before sends Reset request data to D-Bus.
1731 */
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001732 void doPost(crow::Response& res, const crow::Request& req,
Ed Tanouscb13a392020-07-25 19:02:03 +00001733 const std::vector<std::string>&) override
Ed Tanouscc340dd2018-08-29 13:43:38 -07001734 {
Ed Tanous9712f8a2018-09-21 13:38:49 -07001735 auto asyncResp = std::make_shared<AsyncResp>(res);
1736
1737 std::string resetType;
1738 if (!json_util::readJson(req, res, "ResetType", resetType))
Ed Tanouscc340dd2018-08-29 13:43:38 -07001739 {
1740 return;
1741 }
1742
Jason M. Billsd22c8392019-06-03 13:59:03 -07001743 // Get the command and host vs. chassis
Ed Tanous9712f8a2018-09-21 13:38:49 -07001744 std::string command;
Jason M. Billsd22c8392019-06-03 13:59:03 -07001745 bool hostCommand;
Ed Tanousd4d25792020-09-29 15:15:03 -07001746 if ((resetType == "On") || (resetType == "ForceOn"))
Ed Tanous9712f8a2018-09-21 13:38:49 -07001747 {
1748 command = "xyz.openbmc_project.State.Host.Transition.On";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001749 hostCommand = true;
1750 }
1751 else if (resetType == "ForceOff")
1752 {
1753 command = "xyz.openbmc_project.State.Chassis.Transition.Off";
1754 hostCommand = false;
1755 }
Jason M. Billsd22c8392019-06-03 13:59:03 -07001756 else if (resetType == "ForceRestart")
1757 {
Jason M. Bills86a08512020-02-04 13:15:49 -08001758 command =
1759 "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
1760 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001761 }
1762 else if (resetType == "GracefulShutdown")
1763 {
1764 command = "xyz.openbmc_project.State.Host.Transition.Off";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001765 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001766 }
1767 else if (resetType == "GracefulRestart")
1768 {
Jason M. Bills86a08512020-02-04 13:15:49 -08001769 command =
1770 "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001771 hostCommand = true;
1772 }
1773 else if (resetType == "PowerCycle")
1774 {
Jason M. Bills86a08512020-02-04 13:15:49 -08001775 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
1776 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001777 }
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001778 else if (resetType == "Nmi")
1779 {
1780 doNMI(asyncResp);
1781 return;
1782 }
Ed Tanous9712f8a2018-09-21 13:38:49 -07001783 else
1784 {
Jason M. Billsf12894f2018-10-09 12:45:45 -07001785 messages::actionParameterUnknown(res, "Reset", resetType);
Ed Tanous9712f8a2018-09-21 13:38:49 -07001786 return;
1787 }
1788
Jason M. Billsd22c8392019-06-03 13:59:03 -07001789 if (hostCommand)
1790 {
1791 crow::connections::systemBus->async_method_call(
1792 [asyncResp, resetType](const boost::system::error_code ec) {
1793 if (ec)
1794 {
1795 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1796 if (ec.value() == boost::asio::error::invalid_argument)
1797 {
1798 messages::actionParameterNotSupported(
1799 asyncResp->res, resetType, "Reset");
1800 }
1801 else
1802 {
1803 messages::internalError(asyncResp->res);
1804 }
1805 return;
1806 }
1807 messages::success(asyncResp->res);
1808 },
1809 "xyz.openbmc_project.State.Host",
1810 "/xyz/openbmc_project/state/host0",
1811 "org.freedesktop.DBus.Properties", "Set",
1812 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
1813 std::variant<std::string>{command});
1814 }
1815 else
1816 {
1817 crow::connections::systemBus->async_method_call(
1818 [asyncResp, resetType](const boost::system::error_code ec) {
1819 if (ec)
1820 {
1821 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1822 if (ec.value() == boost::asio::error::invalid_argument)
1823 {
1824 messages::actionParameterNotSupported(
1825 asyncResp->res, resetType, "Reset");
1826 }
1827 else
1828 {
1829 messages::internalError(asyncResp->res);
1830 }
1831 return;
1832 }
1833 messages::success(asyncResp->res);
1834 },
1835 "xyz.openbmc_project.State.Chassis",
1836 "/xyz/openbmc_project/state/chassis0",
1837 "org.freedesktop.DBus.Properties", "Set",
1838 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
1839 std::variant<std::string>{command});
1840 }
Ed Tanouscc340dd2018-08-29 13:43:38 -07001841 }
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001842 /**
1843 * Function transceives data with dbus directly.
1844 */
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001845 void doNMI(const std::shared_ptr<AsyncResp>& asyncResp)
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001846 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001847 constexpr char const* serviceName =
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001848 "xyz.openbmc_project.Control.Host.NMI";
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001849 constexpr char const* objectPath =
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001850 "/xyz/openbmc_project/control/host0/nmi";
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001851 constexpr char const* interfaceName =
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001852 "xyz.openbmc_project.Control.Host.NMI";
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001853 constexpr char const* method = "NMI";
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001854
1855 crow::connections::systemBus->async_method_call(
1856 [asyncResp](const boost::system::error_code ec) {
1857 if (ec)
1858 {
1859 BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
1860 messages::internalError(asyncResp->res);
1861 return;
1862 }
1863 messages::success(asyncResp->res);
1864 },
1865 serviceName, objectPath, interfaceName, method);
1866 }
Ed Tanouscc340dd2018-08-29 13:43:38 -07001867};
1868
1869/**
Ed Tanous66173382018-08-15 18:20:59 -07001870 * Systems derived class for delivering Computer Systems Schema.
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001871 */
Ed Tanous1abe55e2018-09-05 08:30:59 -07001872class Systems : public Node
1873{
1874 public:
1875 /*
1876 * Default Constructor
1877 */
Ed Tanous52cc1122020-07-18 13:51:21 -07001878 Systems(App& app) : Node(app, "/redfish/v1/Systems/system/")
Ed Tanous1abe55e2018-09-05 08:30:59 -07001879 {
Ed Tanous1abe55e2018-09-05 08:30:59 -07001880 entityPrivileges = {
1881 {boost::beast::http::verb::get, {{"Login"}}},
1882 {boost::beast::http::verb::head, {{"Login"}}},
1883 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1884 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1885 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1886 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001887 }
1888
Ed Tanous1abe55e2018-09-05 08:30:59 -07001889 private:
Ed Tanous1abe55e2018-09-05 08:30:59 -07001890 /**
1891 * Functions triggers appropriate requests on DBus
1892 */
Ed Tanouscb13a392020-07-25 19:02:03 +00001893 void doGet(crow::Response& res, const crow::Request&,
1894 const std::vector<std::string>&) override
Ed Tanous1abe55e2018-09-05 08:30:59 -07001895 {
Gunnar Millsc0557e12020-06-30 11:26:20 -05001896 res.jsonValue["@odata.type"] = "#ComputerSystem.v1_12_0.ComputerSystem";
Gunnar Mills450a25c2020-04-14 21:34:07 -05001897 res.jsonValue["Name"] = "system";
Ed Tanous029573d2019-02-01 10:57:49 -08001898 res.jsonValue["Id"] = "system";
Ed Tanous0f74e642018-11-12 15:17:05 -08001899 res.jsonValue["SystemType"] = "Physical";
1900 res.jsonValue["Description"] = "Computer System";
Ed Tanous0f74e642018-11-12 15:17:05 -08001901 res.jsonValue["ProcessorSummary"]["Count"] = 0;
1902 res.jsonValue["ProcessorSummary"]["Status"]["State"] = "Disabled";
Cheng C Yang5fd7ba62019-11-28 15:58:08 +08001903 res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = uint64_t(0);
Ed Tanous0f74e642018-11-12 15:17:05 -08001904 res.jsonValue["MemorySummary"]["Status"]["State"] = "Disabled";
Ed Tanous029573d2019-02-01 10:57:49 -08001905 res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
Ed Tanous04a258f2018-10-15 08:00:41 -07001906
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001907 res.jsonValue["Processors"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001908 {"@odata.id", "/redfish/v1/Systems/system/Processors"}};
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001909 res.jsonValue["Memory"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001910 {"@odata.id", "/redfish/v1/Systems/system/Memory"}};
Nikhil Potadea25aecc2019-08-23 16:35:26 -07001911 res.jsonValue["Storage"] = {
1912 {"@odata.id", "/redfish/v1/Systems/system/Storage"}};
Ed Tanous029573d2019-02-01 10:57:49 -08001913
Ed Tanouscc340dd2018-08-29 13:43:38 -07001914 res.jsonValue["Actions"]["#ComputerSystem.Reset"] = {
1915 {"target",
Ed Tanous029573d2019-02-01 10:57:49 -08001916 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"},
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05301917 {"@Redfish.ActionInfo",
1918 "/redfish/v1/Systems/system/ResetActionInfo"}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001919
Jason M. Billsc4bf6372018-11-05 13:48:27 -08001920 res.jsonValue["LogServices"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001921 {"@odata.id", "/redfish/v1/Systems/system/LogServices"}};
Jason M. Billsc4bf6372018-11-05 13:48:27 -08001922
Carol Wangd82a3ac2019-11-21 13:56:38 +08001923 res.jsonValue["Bios"] = {
1924 {"@odata.id", "/redfish/v1/Systems/system/Bios"}};
1925
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001926 res.jsonValue["Links"]["ManagedBy"] = {
1927 {{"@odata.id", "/redfish/v1/Managers/bmc"}}};
1928
1929 res.jsonValue["Status"] = {
1930 {"Health", "OK"},
1931 {"State", "Enabled"},
1932 };
Ed Tanousa0803ef2018-08-29 13:29:23 -07001933 auto asyncResp = std::make_shared<AsyncResp>(res);
Ed Tanous1abe55e2018-09-05 08:30:59 -07001934
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001935 constexpr const std::array<const char*, 4> inventoryForSystems = {
James Feistb49ac872019-05-21 15:12:01 -07001936 "xyz.openbmc_project.Inventory.Item.Dimm",
James Feist2ad9c2f2019-10-29 16:26:48 -07001937 "xyz.openbmc_project.Inventory.Item.Cpu",
James Feiste284a7c2019-11-20 16:20:23 -08001938 "xyz.openbmc_project.Inventory.Item.Drive",
1939 "xyz.openbmc_project.Inventory.Item.StorageController"};
James Feistb49ac872019-05-21 15:12:01 -07001940
1941 auto health = std::make_shared<HealthPopulate>(asyncResp);
1942 crow::connections::systemBus->async_method_call(
1943 [health](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001944 std::vector<std::string>& resp) {
James Feistb49ac872019-05-21 15:12:01 -07001945 if (ec)
1946 {
1947 // no inventory
1948 return;
1949 }
1950
1951 health->inventory = std::move(resp);
1952 },
1953 "xyz.openbmc_project.ObjectMapper",
1954 "/xyz/openbmc_project/object_mapper",
1955 "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", "/",
1956 int32_t(0), inventoryForSystems);
1957
1958 health->populate();
1959
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001960 getMainChassisId(asyncResp, [](const std::string& chassisId,
Ed Tanousb5a76932020-09-29 16:16:58 -07001961 const std::shared_ptr<AsyncResp>& aRsp) {
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001962 aRsp->res.jsonValue["Links"]["Chassis"] = {
1963 {{"@odata.id", "/redfish/v1/Chassis/" + chassisId}}};
1964 });
AppaRao Pulia3002222019-11-12 21:32:59 +05301965
1966 getIndicatorLedState(asyncResp);
James Feist5bc2dc82019-10-22 14:33:16 -07001967 getComputerSystem(asyncResp, health);
Ed Tanous6c34de42018-08-29 13:37:36 -07001968 getHostState(asyncResp);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301969 getBootProperties(asyncResp);
Jason M. Billsadbe1922019-10-14 15:44:35 -07001970 getPCIeDeviceList(asyncResp, "PCIeDevices");
Yong Li51709ff2019-09-30 14:13:04 +08001971 getHostWatchdogTimer(asyncResp);
George Liuc6a620f2020-04-10 17:18:11 +08001972 getPowerRestorePolicy(asyncResp);
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001973 getAutomaticRetry(asyncResp);
Gunnar Millsc0557e12020-06-30 11:26:20 -05001974 getLastResetTime(asyncResp);
AppaRao Pulia6349912019-10-18 17:16:08 +05301975#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1976 getProvisioningStatus(asyncResp);
1977#endif
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001978 }
1979
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001980 void doPatch(crow::Response& res, const crow::Request& req,
Ed Tanouscb13a392020-07-25 19:02:03 +00001981 const std::vector<std::string>&) override
Ed Tanous1abe55e2018-09-05 08:30:59 -07001982 {
Santosh Puranikcde19e52019-02-20 00:10:56 +05301983 std::optional<std::string> indicatorLed;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301984 std::optional<nlohmann::json> bootProps;
Yong Lic45f0082019-10-10 14:19:01 +08001985 std::optional<nlohmann::json> wdtTimerProps;
George Liuc6a620f2020-04-10 17:18:11 +08001986 std::optional<std::string> powerRestorePolicy;
Santosh Puranik41352c22019-07-03 05:35:49 -05001987 auto asyncResp = std::make_shared<AsyncResp>(res);
1988
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001989 if (!json_util::readJson(req, res, "IndicatorLED", indicatorLed, "Boot",
George Liuc6a620f2020-04-10 17:18:11 +08001990 bootProps, "WatchdogTimer", wdtTimerProps,
1991 "PowerRestorePolicy", powerRestorePolicy))
Ed Tanous66173382018-08-15 18:20:59 -07001992 {
Ed Tanous9712f8a2018-09-21 13:38:49 -07001993 return;
1994 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301995
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001996 res.result(boost::beast::http::status::no_content);
Yong Lic45f0082019-10-10 14:19:01 +08001997
1998 if (wdtTimerProps)
1999 {
2000 std::optional<bool> wdtEnable;
2001 std::optional<std::string> wdtTimeOutAction;
2002
2003 if (!json_util::readJson(*wdtTimerProps, asyncResp->res,
2004 "FunctionEnabled", wdtEnable,
2005 "TimeoutAction", wdtTimeOutAction))
2006 {
2007 return;
2008 }
Ed Tanousf23b7292020-10-15 09:41:17 -07002009 setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
Yong Lic45f0082019-10-10 14:19:01 +08002010 }
2011
Santosh Puranik491d8ee2019-02-06 19:46:56 +05302012 if (bootProps)
2013 {
2014 std::optional<std::string> bootSource;
2015 std::optional<std::string> bootEnable;
Gunnar Mills69f35302020-05-17 16:06:31 -05002016 std::optional<std::string> automaticRetryConfig;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05302017
Gunnar Mills69f35302020-05-17 16:06:31 -05002018 if (!json_util::readJson(
2019 *bootProps, asyncResp->res, "BootSourceOverrideTarget",
2020 bootSource, "BootSourceOverrideEnabled", bootEnable,
2021 "AutomaticRetryConfig", automaticRetryConfig))
Santosh Puranik491d8ee2019-02-06 19:46:56 +05302022 {
2023 return;
2024 }
Gunnar Mills69f35302020-05-17 16:06:31 -05002025 if (bootSource || bootEnable)
2026 {
2027 setBootSourceProperties(asyncResp, std::move(bootSource),
2028 std::move(bootEnable));
2029 }
2030 if (automaticRetryConfig)
2031 {
Ed Tanousf23b7292020-10-15 09:41:17 -07002032 setAutomaticRetry(asyncResp, *automaticRetryConfig);
Gunnar Mills69f35302020-05-17 16:06:31 -05002033 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05302034 }
Johnathan Mantey265c1602019-08-08 11:02:51 -07002035
Ed Tanous9712f8a2018-09-21 13:38:49 -07002036 if (indicatorLed)
2037 {
Ed Tanousf23b7292020-10-15 09:41:17 -07002038 setIndicatorLedState(asyncResp, *indicatorLed);
Ed Tanous1abe55e2018-09-05 08:30:59 -07002039 }
George Liuc6a620f2020-04-10 17:18:11 +08002040
2041 if (powerRestorePolicy)
2042 {
2043 setPowerRestorePolicy(asyncResp, std::move(*powerRestorePolicy));
2044 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002045 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002046};
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05302047
2048/**
2049 * SystemResetActionInfo derived class for delivering Computer Systems
2050 * ResetType AllowableValues using ResetInfo schema.
2051 */
2052class SystemResetActionInfo : public Node
2053{
2054 public:
2055 /*
2056 * Default Constructor
2057 */
Ed Tanous52cc1122020-07-18 13:51:21 -07002058 SystemResetActionInfo(App& app) :
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05302059 Node(app, "/redfish/v1/Systems/system/ResetActionInfo/")
2060 {
2061 entityPrivileges = {
2062 {boost::beast::http::verb::get, {{"Login"}}},
2063 {boost::beast::http::verb::head, {{"Login"}}},
2064 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
2065 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
2066 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
2067 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
2068 }
2069
2070 private:
2071 /**
2072 * Functions triggers appropriate requests on DBus
2073 */
Ed Tanouscb13a392020-07-25 19:02:03 +00002074 void doGet(crow::Response& res, const crow::Request&,
2075 const std::vector<std::string>&) override
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05302076 {
2077 res.jsonValue = {
2078 {"@odata.type", "#ActionInfo.v1_1_2.ActionInfo"},
2079 {"@odata.id", "/redfish/v1/Systems/system/ResetActionInfo"},
2080 {"Name", "Reset Action Info"},
2081 {"Id", "ResetActionInfo"},
2082 {"Parameters",
2083 {{{"Name", "ResetType"},
2084 {"Required", true},
2085 {"DataType", "String"},
2086 {"AllowableValues",
2087 {"On", "ForceOff", "ForceOn", "ForceRestart", "GracefulRestart",
2088 "GracefulShutdown", "PowerCycle", "Nmi"}}}}}};
2089 res.end();
2090 }
2091};
Ed Tanous1abe55e2018-09-05 08:30:59 -07002092} // namespace redfish