blob: abe8b02e4b21b7edc6f712fd503b879d410581bd [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
Jonathan Doman1e1e5982021-06-11 09:36:17 -070018#include "dbus_singleton.hpp"
James Feistb49ac872019-05-21 15:12:01 -070019#include "health.hpp"
James Feist1c8fba92019-12-20 15:12:07 -080020#include "led.hpp"
Jason M. Billsf5c9f8b2018-12-18 16:51:18 -080021#include "pcie.hpp"
Jennifer Leec5d03ff2019-03-08 15:42:58 -080022#include "redfish_util.hpp"
23
John Edward Broadbent7e860f12021-04-08 15:57:16 -070024#include <app.hpp>
Ed Tanous9712f8a2018-09-21 13:38:49 -070025#include <boost/container/flat_map.hpp>
Ed Tanous168e20c2021-12-13 14:39:53 -080026#include <dbus_utility.hpp>
Ed Tanoused398212021-06-09 17:05:54 -070027#include <registries/privilege_registry.hpp>
Jonathan Doman1e1e5982021-06-11 09:36:17 -070028#include <sdbusplus/asio/property.hpp>
Andrew Geisslercb7e1e72019-02-19 13:05:38 -060029#include <utils/fw_utils.hpp>
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020030#include <utils/json_utils.hpp>
Gunnar Mills1214b7e2020-06-04 10:11:30 -050031
Ed Tanousabf2add2019-01-22 16:40:12 -080032#include <variant>
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020033
Ed Tanous1abe55e2018-09-05 08:30:59 -070034namespace redfish
35{
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020036
Alpana Kumari9d3ae102019-04-12 06:49:32 -050037/**
38 * @brief Updates the Functional State of DIMMs
39 *
40 * @param[in] aResp Shared pointer for completing asynchronous calls
41 * @param[in] dimmState Dimm's Functional state, true/false
42 *
43 * @return None.
44 */
zhanghch058d1b46d2021-04-01 11:18:24 +080045inline void
46 updateDimmProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Jonathan Doman1e1e5982021-06-11 09:36:17 -070047 bool isDimmFunctional)
Alpana Kumari9d3ae102019-04-12 06:49:32 -050048{
Jonathan Doman1e1e5982021-06-11 09:36:17 -070049 BMCWEB_LOG_DEBUG << "Dimm Functional: " << isDimmFunctional;
Alpana Kumari9d3ae102019-04-12 06:49:32 -050050
Gunnar Mills4e0453b2020-07-08 14:00:30 -050051 // Set it as Enabled if at least one DIMM is functional
Alpana Kumari9d3ae102019-04-12 06:49:32 -050052 // Update STATE only if previous State was DISABLED and current Dimm is
53 // ENABLED.
Gunnar Mills1214b7e2020-06-04 10:11:30 -050054 nlohmann::json& prevMemSummary =
Alpana Kumari9d3ae102019-04-12 06:49:32 -050055 aResp->res.jsonValue["MemorySummary"]["Status"]["State"];
56 if (prevMemSummary == "Disabled")
57 {
Jonathan Doman1e1e5982021-06-11 09:36:17 -070058 if (isDimmFunctional == true)
Alpana Kumari9d3ae102019-04-12 06:49:32 -050059 {
60 aResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
61 "Enabled";
62 }
63 }
64}
65
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050066/*
67 * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState
68 *
69 * @param[in] aResp Shared pointer for completing asynchronous calls
70 * @param[in] cpuPresenceState CPU present or not
71 *
72 * @return None.
73 */
Jonathan Doman1e1e5982021-06-11 09:36:17 -070074inline void
75 modifyCpuPresenceState(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
76 bool isCpuPresent)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050077{
Jonathan Doman1e1e5982021-06-11 09:36:17 -070078 BMCWEB_LOG_DEBUG << "Cpu Present: " << isCpuPresent;
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050079
Jonathan Doman1e1e5982021-06-11 09:36:17 -070080 if (isCpuPresent == true)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050081 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -050082 nlohmann::json& procCount =
James Feistb4b95952019-12-05 15:01:55 -080083 aResp->res.jsonValue["ProcessorSummary"]["Count"];
84 auto procCountPtr =
Gunnar Mills1214b7e2020-06-04 10:11:30 -050085 procCount.get_ptr<nlohmann::json::number_integer_t*>();
James Feistb4b95952019-12-05 15:01:55 -080086 if (procCountPtr != nullptr)
87 {
88 // shouldn't be possible to be nullptr
89 *procCountPtr += 1;
90 }
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050091 }
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050092}
93
94/*
95 * @brief Update "ProcessorSummary" "Status" "State" based on
96 * CPU Functional State
97 *
98 * @param[in] aResp Shared pointer for completing asynchronous calls
99 * @param[in] cpuFunctionalState is CPU functional true/false
100 *
101 * @return None.
102 */
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700103inline void
104 modifyCpuFunctionalState(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
105 bool isCpuFunctional)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500106{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700107 BMCWEB_LOG_DEBUG << "Cpu Functional: " << isCpuFunctional;
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500108
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500109 nlohmann::json& prevProcState =
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500110 aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"];
111
Gunnar Mills4e0453b2020-07-08 14:00:30 -0500112 // Set it as Enabled if at least one CPU is functional
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500113 // Update STATE only if previous State was Non_Functional and current CPU is
114 // Functional.
115 if (prevProcState == "Disabled")
116 {
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700117 if (isCpuFunctional == true)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500118 {
119 aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
120 "Enabled";
121 }
122 }
123}
124
Ali Ahmed03fbed92021-09-03 02:33:43 -0500125inline void getProcessorProperties(
126 const std::shared_ptr<bmcweb::AsyncResp>& aResp, const std::string& service,
127 const std::string& path,
Ed Tanous168e20c2021-12-13 14:39:53 -0800128 const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>&
Ali Ahmed03fbed92021-09-03 02:33:43 -0500129 properties)
130{
131
132 BMCWEB_LOG_DEBUG << "Got " << properties.size() << " Cpu properties.";
133
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700134 auto getCpuPresenceState = [aResp](const boost::system::error_code ec3,
135 const bool cpuPresenceCheck) {
136 if (ec3)
137 {
138 BMCWEB_LOG_ERROR << "DBUS response error " << ec3;
139 return;
140 }
141 modifyCpuPresenceState(aResp, cpuPresenceCheck);
142 };
Ali Ahmed03fbed92021-09-03 02:33:43 -0500143
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700144 auto getCpuFunctionalState = [aResp](const boost::system::error_code ec3,
145 const bool cpuFunctionalCheck) {
146 if (ec3)
147 {
148 BMCWEB_LOG_ERROR << "DBUS response error " << ec3;
149 return;
150 }
151 modifyCpuFunctionalState(aResp, cpuFunctionalCheck);
152 };
Ali Ahmed03fbed92021-09-03 02:33:43 -0500153
154 // Get the Presence of CPU
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700155 sdbusplus::asio::getProperty<bool>(
156 *crow::connections::systemBus, service, path,
157 "xyz.openbmc_project.Inventory.Item", "Present",
158 std::move(getCpuPresenceState));
Ali Ahmed03fbed92021-09-03 02:33:43 -0500159
160 // Get the Functional State
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700161 sdbusplus::asio::getProperty<bool>(
162 *crow::connections::systemBus, service, path,
163 "xyz.openbmc_project.State.Decorator.OperationalStatus", "Functional",
164 std::move(getCpuFunctionalState));
Ali Ahmed03fbed92021-09-03 02:33:43 -0500165
166 for (const auto& property : properties)
167 {
168
169 // TODO: Get Model
170
171 // Get CoreCount
172 if (property.first == "CoreCount")
173 {
174
175 // Get CPU CoreCount and add it to the total
176 const uint16_t* coreCountVal =
177 std::get_if<uint16_t>(&property.second);
178
179 if (!coreCountVal)
180 {
181 messages::internalError(aResp->res);
182 return;
183 }
184
185 nlohmann::json& coreCount =
186 aResp->res.jsonValue["ProcessorSummary"]["CoreCount"];
187 uint64_t* coreCountPtr = coreCount.get_ptr<uint64_t*>();
188
189 if (coreCountPtr == nullptr)
190 {
191 coreCount = 0;
192 }
193 else
194 {
195 *coreCountPtr += *coreCountVal;
196 }
197 }
198 }
199}
200
201/*
202 * @brief Get ProcessorSummary fields
203 *
204 * @param[in] aResp Shared pointer for completing asynchronous calls
205 * @param[in] service dbus service for Cpu Information
206 * @param[in] path dbus path for Cpu
207 *
208 * @return None.
209 */
210inline void getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
211 const std::string& service,
212 const std::string& path)
213{
214
215 crow::connections::systemBus->async_method_call(
216 [aResp, service,
217 path](const boost::system::error_code ec2,
218 const std::vector<std::pair<
Ed Tanous168e20c2021-12-13 14:39:53 -0800219 std::string, dbus::utility::DbusVariantType>>& properties) {
Ali Ahmed03fbed92021-09-03 02:33:43 -0500220 if (ec2)
221 {
222 BMCWEB_LOG_ERROR << "DBUS response error " << ec2;
223 messages::internalError(aResp->res);
224 return;
225 }
226 getProcessorProperties(aResp, service, path, properties);
227 },
228 service, path, "org.freedesktop.DBus.Properties", "GetAll",
229 "xyz.openbmc_project.Inventory.Item.Cpu");
230}
231
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500232/*
Ed Tanous6c34de42018-08-29 13:37:36 -0700233 * @brief Retrieves computer system properties over dbus
234 *
235 * @param[in] aResp Shared pointer for completing asynchronous calls
Gunnar Mills8f9ee3c2020-10-30 16:15:13 -0500236 * @param[in] systemHealth Shared HealthPopulate pointer
Ed Tanous6c34de42018-08-29 13:37:36 -0700237 *
238 * @return None.
239 */
Ed Tanousb5a76932020-09-29 16:16:58 -0700240inline void
zhanghch058d1b46d2021-04-01 11:18:24 +0800241 getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Ed Tanousb5a76932020-09-29 16:16:58 -0700242 const std::shared_ptr<HealthPopulate>& systemHealth)
Ed Tanous6c34de42018-08-29 13:37:36 -0700243{
Ed Tanous6c34de42018-08-29 13:37:36 -0700244 BMCWEB_LOG_DEBUG << "Get available system components.";
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500245
Ed Tanous6c34de42018-08-29 13:37:36 -0700246 crow::connections::systemBus->async_method_call(
James Feist5bc2dc82019-10-22 14:33:16 -0700247 [aResp, systemHealth](
Ed Tanous6c34de42018-08-29 13:37:36 -0700248 const boost::system::error_code ec,
249 const std::vector<std::pair<
250 std::string,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500251 std::vector<std::pair<std::string, std::vector<std::string>>>>>&
252 subtree) {
Ed Tanous6c34de42018-08-29 13:37:36 -0700253 if (ec)
254 {
255 BMCWEB_LOG_DEBUG << "DBUS response error";
Jason M. Billsf12894f2018-10-09 12:45:45 -0700256 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700257 return;
258 }
Ed Tanous6c34de42018-08-29 13:37:36 -0700259 // Iterate over all retrieved ObjectPaths.
260 for (const std::pair<std::string,
261 std::vector<std::pair<
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500262 std::string, std::vector<std::string>>>>&
263 object : subtree)
Ed Tanous6c34de42018-08-29 13:37:36 -0700264 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500265 const std::string& path = object.first;
Ed Tanous6c34de42018-08-29 13:37:36 -0700266 BMCWEB_LOG_DEBUG << "Got path: " << path;
267 const std::vector<
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500268 std::pair<std::string, std::vector<std::string>>>&
269 connectionNames = object.second;
Ed Tanous6c34de42018-08-29 13:37:36 -0700270 if (connectionNames.size() < 1)
271 {
272 continue;
273 }
Ed Tanous029573d2019-02-01 10:57:49 -0800274
James Feist5bc2dc82019-10-22 14:33:16 -0700275 auto memoryHealth = std::make_shared<HealthPopulate>(
276 aResp, aResp->res.jsonValue["MemorySummary"]["Status"]);
277
278 auto cpuHealth = std::make_shared<HealthPopulate>(
279 aResp, aResp->res.jsonValue["ProcessorSummary"]["Status"]);
280
281 systemHealth->children.emplace_back(memoryHealth);
282 systemHealth->children.emplace_back(cpuHealth);
283
Ed Tanous029573d2019-02-01 10:57:49 -0800284 // This is not system, so check if it's cpu, dimm, UUID or
285 // BiosVer
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500286 for (const auto& connection : connectionNames)
Ed Tanous6c34de42018-08-29 13:37:36 -0700287 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500288 for (const auto& interfaceName : connection.second)
Ed Tanous6c34de42018-08-29 13:37:36 -0700289 {
Ed Tanous029573d2019-02-01 10:57:49 -0800290 if (interfaceName ==
291 "xyz.openbmc_project.Inventory.Item.Dimm")
Ed Tanous6c34de42018-08-29 13:37:36 -0700292 {
Ed Tanous029573d2019-02-01 10:57:49 -0800293 BMCWEB_LOG_DEBUG
294 << "Found Dimm, now get its properties.";
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500295
Ed Tanous029573d2019-02-01 10:57:49 -0800296 crow::connections::systemBus->async_method_call(
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500297 [aResp, service{connection.first},
Ed Tanousf23b7292020-10-15 09:41:17 -0700298 path](const boost::system::error_code ec2,
Ed Tanous168e20c2021-12-13 14:39:53 -0800299 const std::vector<std::pair<
300 std::string,
301 dbus::utility::DbusVariantType>>&
Ed Tanousf23b7292020-10-15 09:41:17 -0700302 properties) {
Ed Tanouscb13a392020-07-25 19:02:03 +0000303 if (ec2)
Ed Tanous029573d2019-02-01 10:57:49 -0800304 {
305 BMCWEB_LOG_ERROR
Ed Tanouscb13a392020-07-25 19:02:03 +0000306 << "DBUS response error " << ec2;
Ed Tanous029573d2019-02-01 10:57:49 -0800307 messages::internalError(aResp->res);
308 return;
309 }
310 BMCWEB_LOG_DEBUG << "Got "
311 << properties.size()
Gunnar Mills698654b2019-10-16 13:17:37 -0500312 << " Dimm properties.";
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500313
314 if (properties.size() > 0)
Ed Tanous029573d2019-02-01 10:57:49 -0800315 {
Ed Tanous168e20c2021-12-13 14:39:53 -0800316 for (const std::pair<
317 std::string,
318 dbus::utility::
319 DbusVariantType>&
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500320 property : properties)
Ed Tanous6c34de42018-08-29 13:37:36 -0700321 {
Cheng C Yang5fd7ba62019-11-28 15:58:08 +0800322 if (property.first !=
323 "MemorySizeInKB")
Ed Tanous6c34de42018-08-29 13:37:36 -0700324 {
Cheng C Yang5fd7ba62019-11-28 15:58:08 +0800325 continue;
Ed Tanous6c34de42018-08-29 13:37:36 -0700326 }
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500327 const uint32_t* value =
Patrick Williams8d78b7a2020-05-13 11:24:20 -0500328 std::get_if<uint32_t>(
329 &property.second);
Cheng C Yang5fd7ba62019-11-28 15:58:08 +0800330 if (value == nullptr)
331 {
332 BMCWEB_LOG_DEBUG
George Liu0fda0f12021-11-16 10:06:17 +0800333 << "Find incorrect type of MemorySize";
Cheng C Yang5fd7ba62019-11-28 15:58:08 +0800334 continue;
335 }
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500336 nlohmann::json& totalMemory =
George Liu0fda0f12021-11-16 10:06:17 +0800337 aResp->res.jsonValue
338 ["MemorySummary"]
339 ["TotalSystemMemoryGiB"];
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500340 uint64_t* preValue =
Cheng C Yang5fd7ba62019-11-28 15:58:08 +0800341 totalMemory
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500342 .get_ptr<uint64_t*>();
Cheng C Yang5fd7ba62019-11-28 15:58:08 +0800343 if (preValue == nullptr)
344 {
345 continue;
346 }
George Liu0fda0f12021-11-16 10:06:17 +0800347 aResp->res.jsonValue
348 ["MemorySummary"]
349 ["TotalSystemMemoryGiB"] =
Cheng C Yang5fd7ba62019-11-28 15:58:08 +0800350 *value / (1024 * 1024) +
351 *preValue;
352 aResp->res
353 .jsonValue["MemorySummary"]
354 ["Status"]["State"] =
355 "Enabled";
Ed Tanous6c34de42018-08-29 13:37:36 -0700356 }
Ed Tanous029573d2019-02-01 10:57:49 -0800357 }
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500358 else
359 {
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700360 sdbusplus::asio::getProperty<bool>(
361 *crow::connections::systemBus,
362 service, path,
363 "xyz.openbmc_project.State."
364 "Decorator.OperationalStatus",
365 "Functional",
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500366 [aResp](
367 const boost::system::error_code
Ed Tanouscb13a392020-07-25 19:02:03 +0000368 ec3,
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700369 bool dimmState) {
Ed Tanouscb13a392020-07-25 19:02:03 +0000370 if (ec3)
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500371 {
372 BMCWEB_LOG_ERROR
George Liu0fda0f12021-11-16 10:06:17 +0800373 << "DBUS response error "
Ed Tanouscb13a392020-07-25 19:02:03 +0000374 << ec3;
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500375 return;
376 }
377 updateDimmProperties(aResp,
378 dimmState);
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700379 });
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500380 }
Ed Tanous029573d2019-02-01 10:57:49 -0800381 },
382 connection.first, path,
383 "org.freedesktop.DBus.Properties", "GetAll",
384 "xyz.openbmc_project.Inventory.Item.Dimm");
James Feist5bc2dc82019-10-22 14:33:16 -0700385
386 memoryHealth->inventory.emplace_back(path);
Ed Tanous029573d2019-02-01 10:57:49 -0800387 }
388 else if (interfaceName ==
389 "xyz.openbmc_project.Inventory.Item.Cpu")
390 {
391 BMCWEB_LOG_DEBUG
392 << "Found Cpu, now get its properties.";
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500393
Ali Ahmed03fbed92021-09-03 02:33:43 -0500394 getProcessorSummary(aResp, connection.first, path);
James Feist5bc2dc82019-10-22 14:33:16 -0700395
396 cpuHealth->inventory.emplace_back(path);
Ed Tanous029573d2019-02-01 10:57:49 -0800397 }
398 else if (interfaceName ==
399 "xyz.openbmc_project.Common.UUID")
400 {
401 BMCWEB_LOG_DEBUG
402 << "Found UUID, now get its properties.";
403 crow::connections::systemBus->async_method_call(
Ed Tanous168e20c2021-12-13 14:39:53 -0800404 [aResp](const boost::system::error_code ec3,
405 const std::vector<std::pair<
406 std::string,
407 dbus::utility::DbusVariantType>>&
408 properties) {
Ed Tanouscb13a392020-07-25 19:02:03 +0000409 if (ec3)
Ed Tanous029573d2019-02-01 10:57:49 -0800410 {
411 BMCWEB_LOG_DEBUG
Ed Tanouscb13a392020-07-25 19:02:03 +0000412 << "DBUS response error " << ec3;
Ed Tanous029573d2019-02-01 10:57:49 -0800413 messages::internalError(aResp->res);
414 return;
415 }
416 BMCWEB_LOG_DEBUG << "Got "
417 << properties.size()
Gunnar Mills698654b2019-10-16 13:17:37 -0500418 << " UUID properties.";
Ed Tanous168e20c2021-12-13 14:39:53 -0800419 for (const std::pair<
420 std::string,
421 dbus::utility::DbusVariantType>&
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500422 property : properties)
Ed Tanous029573d2019-02-01 10:57:49 -0800423 {
Ed Tanous029573d2019-02-01 10:57:49 -0800424 if (property.first == "UUID")
425 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500426 const std::string* value =
Patrick Williams8d78b7a2020-05-13 11:24:20 -0500427 std::get_if<std::string>(
428 &property.second);
Ed Tanous04a258f2018-10-15 08:00:41 -0700429
Ed Tanous029573d2019-02-01 10:57:49 -0800430 if (value != nullptr)
431 {
432 std::string valueStr = *value;
433 if (valueStr.size() == 32)
Ed Tanous6c34de42018-08-29 13:37:36 -0700434 {
Ed Tanous029573d2019-02-01 10:57:49 -0800435 valueStr.insert(8, 1, '-');
436 valueStr.insert(13, 1, '-');
437 valueStr.insert(18, 1, '-');
438 valueStr.insert(23, 1, '-');
Ed Tanous6c34de42018-08-29 13:37:36 -0700439 }
Ed Tanous029573d2019-02-01 10:57:49 -0800440 BMCWEB_LOG_DEBUG << "UUID = "
441 << valueStr;
442 aResp->res.jsonValue["UUID"] =
443 valueStr;
Ed Tanous6c34de42018-08-29 13:37:36 -0700444 }
445 }
Ed Tanous029573d2019-02-01 10:57:49 -0800446 }
447 },
448 connection.first, path,
449 "org.freedesktop.DBus.Properties", "GetAll",
450 "xyz.openbmc_project.Common.UUID");
451 }
452 else if (interfaceName ==
453 "xyz.openbmc_project.Inventory.Item.System")
454 {
455 crow::connections::systemBus->async_method_call(
Ed Tanous168e20c2021-12-13 14:39:53 -0800456 [aResp](const boost::system::error_code ec2,
457 const std::vector<std::pair<
458 std::string,
459 dbus::utility::DbusVariantType>>&
460 propertiesList) {
Ed Tanouscb13a392020-07-25 19:02:03 +0000461 if (ec2)
Ed Tanous029573d2019-02-01 10:57:49 -0800462 {
James Feiste4a4b9a2019-06-20 14:08:07 -0700463 // doesn't have to include this
464 // interface
Ed Tanous029573d2019-02-01 10:57:49 -0800465 return;
466 }
Gunnar Mills698654b2019-10-16 13:17:37 -0500467 BMCWEB_LOG_DEBUG
468 << "Got " << propertiesList.size()
469 << " properties for system";
Ed Tanous168e20c2021-12-13 14:39:53 -0800470 for (const std::pair<
471 std::string,
472 dbus::utility::DbusVariantType>&
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500473 property : propertiesList)
Ed Tanous029573d2019-02-01 10:57:49 -0800474 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500475 const std::string& propertyName =
beccabroekfc5afcf2019-03-05 14:35:15 -0600476 property.first;
477 if ((propertyName == "PartNumber") ||
478 (propertyName == "SerialNumber") ||
479 (propertyName == "Manufacturer") ||
SunnySrivastava19845235d962020-06-30 03:09:00 -0500480 (propertyName == "Model") ||
481 (propertyName == "SubModel"))
Ed Tanous029573d2019-02-01 10:57:49 -0800482 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500483 const std::string* value =
beccabroekfc5afcf2019-03-05 14:35:15 -0600484 std::get_if<std::string>(
485 &property.second);
486 if (value != nullptr)
487 {
488 aResp->res
489 .jsonValue[propertyName] =
490 *value;
491 }
Ed Tanous029573d2019-02-01 10:57:49 -0800492 }
493 }
Gunnar Millsc1e236a2020-04-14 21:36:33 -0500494
Andrew Geisslercb7e1e72019-02-19 13:05:38 -0600495 // Grab the bios version
Gunnar Millsf97ddba2020-08-20 15:57:40 -0500496 fw_util::populateFirmwareInformation(
Andrew Geisslercb7e1e72019-02-19 13:05:38 -0600497 aResp, fw_util::biosPurpose,
Gunnar Mills72d566d2020-07-21 12:44:00 -0500498 "BiosVersion", false);
Ed Tanous029573d2019-02-01 10:57:49 -0800499 },
500 connection.first, path,
501 "org.freedesktop.DBus.Properties", "GetAll",
George Liu0fda0f12021-11-16 10:06:17 +0800502 "xyz.openbmc_project.Inventory.Decorator.Asset");
James Feiste4a4b9a2019-06-20 14:08:07 -0700503
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700504 sdbusplus::asio::getProperty<std::string>(
505 *crow::connections::systemBus, connection.first,
506 path,
507 "xyz.openbmc_project.Inventory.Decorator."
508 "AssetTag",
509 "AssetTag",
Ed Tanous168e20c2021-12-13 14:39:53 -0800510 [aResp](const boost::system::error_code ec2,
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700511 const std::string& value) {
Ed Tanouscb13a392020-07-25 19:02:03 +0000512 if (ec2)
James Feiste4a4b9a2019-06-20 14:08:07 -0700513 {
514 // doesn't have to include this
515 // interface
516 return;
517 }
518
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700519 aResp->res.jsonValue["AssetTag"] = value;
520 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700521 }
522 }
523 }
524 }
Ed Tanous6c34de42018-08-29 13:37:36 -0700525 },
526 "xyz.openbmc_project.ObjectMapper",
527 "/xyz/openbmc_project/object_mapper",
528 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
Ed Tanous66173382018-08-15 18:20:59 -0700529 "/xyz/openbmc_project/inventory", int32_t(0),
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500530 std::array<const char*, 5>{
Ed Tanous66173382018-08-15 18:20:59 -0700531 "xyz.openbmc_project.Inventory.Decorator.Asset",
532 "xyz.openbmc_project.Inventory.Item.Cpu",
533 "xyz.openbmc_project.Inventory.Item.Dimm",
534 "xyz.openbmc_project.Inventory.Item.System",
535 "xyz.openbmc_project.Common.UUID",
536 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700537}
538
539/**
Ed Tanous6c34de42018-08-29 13:37:36 -0700540 * @brief Retrieves host state properties over dbus
541 *
542 * @param[in] aResp Shared pointer for completing asynchronous calls.
543 *
544 * @return None.
545 */
zhanghch058d1b46d2021-04-01 11:18:24 +0800546inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
Ed Tanous6c34de42018-08-29 13:37:36 -0700547{
548 BMCWEB_LOG_DEBUG << "Get host information.";
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700549 sdbusplus::asio::getProperty<std::string>(
550 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
551 "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host",
552 "CurrentHostState",
Jennifer Leec5d03ff2019-03-08 15:42:58 -0800553 [aResp](const boost::system::error_code ec,
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700554 const std::string& hostState) {
Ed Tanous6c34de42018-08-29 13:37:36 -0700555 if (ec)
556 {
557 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700558 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700559 return;
560 }
Ed Tanous66173382018-08-15 18:20:59 -0700561
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700562 BMCWEB_LOG_DEBUG << "Host state: " << hostState;
563 // Verify Host State
564 if (hostState == "xyz.openbmc_project.State.Host.HostState.Running")
Ed Tanous6c34de42018-08-29 13:37:36 -0700565 {
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700566 aResp->res.jsonValue["PowerState"] = "On";
567 aResp->res.jsonValue["Status"]["State"] = "Enabled";
Ed Tanous6c34de42018-08-29 13:37:36 -0700568 }
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700569 else if (hostState ==
570 "xyz.openbmc_project.State.Host.HostState.Quiesced")
571 {
572 aResp->res.jsonValue["PowerState"] = "On";
573 aResp->res.jsonValue["Status"]["State"] = "Quiesced";
574 }
575 else if (hostState ==
576 "xyz.openbmc_project.State.Host.HostState.DiagnosticMode")
577 {
578 aResp->res.jsonValue["PowerState"] = "On";
579 aResp->res.jsonValue["Status"]["State"] = "InTest";
580 }
581 else if (
582 hostState ==
583 "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning")
584 {
585 aResp->res.jsonValue["PowerState"] = "PoweringOn";
586 aResp->res.jsonValue["Status"]["State"] = "Starting";
587 }
588 else if (
589 hostState ==
590 "xyz.openbmc_project.State.Host.HostState.TransitioningToOff")
591 {
592 aResp->res.jsonValue["PowerState"] = "PoweringOff";
593 aResp->res.jsonValue["Status"]["State"] = "Disabled";
594 }
595 else
596 {
597 aResp->res.jsonValue["PowerState"] = "Off";
598 aResp->res.jsonValue["Status"]["State"] = "Disabled";
599 }
600 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700601}
602
603/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500604 * @brief Translates boot source DBUS property value to redfish.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530605 *
606 * @param[in] dbusSource The boot source in DBUS speak.
607 *
608 * @return Returns as a string, the boot source in Redfish terms. If translation
609 * cannot be done, returns an empty string.
610 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000611inline std::string dbusToRfBootSource(const std::string& dbusSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530612{
613 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
614 {
615 return "None";
616 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700617 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530618 {
619 return "Hdd";
620 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700621 if (dbusSource ==
622 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530623 {
624 return "Cd";
625 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700626 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530627 {
628 return "Pxe";
629 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700630 if (dbusSource ==
631 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700632 {
633 return "Usb";
634 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700635 return "";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530636}
637
638/**
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300639 * @brief Translates boot type DBUS property value to redfish.
640 *
641 * @param[in] dbusType The boot type in DBUS speak.
642 *
643 * @return Returns as a string, the boot type in Redfish terms. If translation
644 * cannot be done, returns an empty string.
645 */
646inline std::string dbusToRfBootType(const std::string& dbusType)
647{
648 if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy")
649 {
650 return "Legacy";
651 }
652 if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI")
653 {
654 return "UEFI";
655 }
656 return "";
657}
658
659/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500660 * @brief Translates boot mode DBUS property value to redfish.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530661 *
662 * @param[in] dbusMode The boot mode in DBUS speak.
663 *
664 * @return Returns as a string, the boot mode in Redfish terms. If translation
665 * cannot be done, returns an empty string.
666 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000667inline std::string dbusToRfBootMode(const std::string& dbusMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530668{
669 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
670 {
671 return "None";
672 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700673 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530674 {
675 return "Diags";
676 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700677 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530678 {
679 return "BiosSetup";
680 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700681 return "";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530682}
683
684/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500685 * @brief Translates boot source from Redfish to the DBus boot paths.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530686 *
687 * @param[in] rfSource The boot source in Redfish.
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700688 * @param[out] bootSource The DBus source
689 * @param[out] bootMode the DBus boot mode
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530690 *
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700691 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530692 */
zhanghch058d1b46d2021-04-01 11:18:24 +0800693inline int assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500694 const std::string& rfSource,
695 std::string& bootSource, std::string& bootMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530696{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300697 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
698 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700699
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530700 if (rfSource == "None")
701 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700702 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530703 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700704 if (rfSource == "Pxe")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530705 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700706 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
707 }
708 else if (rfSource == "Hdd")
709 {
710 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
711 }
712 else if (rfSource == "Diags")
713 {
714 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
715 }
716 else if (rfSource == "Cd")
717 {
718 bootSource =
719 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
720 }
721 else if (rfSource == "BiosSetup")
722 {
723 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530724 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700725 else if (rfSource == "Usb")
726 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700727 bootSource =
728 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700729 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530730 else
731 {
George Liu0fda0f12021-11-16 10:06:17 +0800732 BMCWEB_LOG_DEBUG
733 << "Invalid property value for BootSourceOverrideTarget: "
734 << bootSource;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700735 messages::propertyValueNotInList(aResp->res, rfSource,
736 "BootSourceTargetOverride");
737 return -1;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530738 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700739 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530740}
Ali Ahmed19817712021-06-29 17:01:52 -0500741
Andrew Geissler978b8802020-11-19 13:36:40 -0600742/**
743 * @brief Retrieves boot progress of the system
744 *
745 * @param[in] aResp Shared pointer for generating response message.
746 *
747 * @return None.
748 */
zhanghch058d1b46d2021-04-01 11:18:24 +0800749inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
Andrew Geissler978b8802020-11-19 13:36:40 -0600750{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700751 sdbusplus::asio::getProperty<std::string>(
752 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
753 "/xyz/openbmc_project/state/host0",
754 "xyz.openbmc_project.State.Boot.Progress", "BootProgress",
Andrew Geissler978b8802020-11-19 13:36:40 -0600755 [aResp](const boost::system::error_code ec,
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700756 const std::string& bootProgressStr) {
Andrew Geissler978b8802020-11-19 13:36:40 -0600757 if (ec)
758 {
759 // BootProgress is an optional object so just do nothing if
760 // not found
761 return;
762 }
763
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700764 BMCWEB_LOG_DEBUG << "Boot Progress: " << bootProgressStr;
Andrew Geissler978b8802020-11-19 13:36:40 -0600765
766 // Now convert the D-Bus BootProgress to the appropriate Redfish
767 // enum
768 std::string rfBpLastState = "None";
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700769 if (bootProgressStr ==
George Liu0fda0f12021-11-16 10:06:17 +0800770 "xyz.openbmc_project.State.Boot.Progress.ProgressStages.Unspecified")
Andrew Geissler978b8802020-11-19 13:36:40 -0600771 {
772 rfBpLastState = "None";
773 }
George Liu0fda0f12021-11-16 10:06:17 +0800774 else if (
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700775 bootProgressStr ==
George Liu0fda0f12021-11-16 10:06:17 +0800776 "xyz.openbmc_project.State.Boot.Progress.ProgressStages.PrimaryProcInit")
Andrew Geissler978b8802020-11-19 13:36:40 -0600777 {
778 rfBpLastState = "PrimaryProcessorInitializationStarted";
779 }
George Liu0fda0f12021-11-16 10:06:17 +0800780 else if (
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700781 bootProgressStr ==
George Liu0fda0f12021-11-16 10:06:17 +0800782 "xyz.openbmc_project.State.Boot.Progress.ProgressStages.BusInit")
Andrew Geissler978b8802020-11-19 13:36:40 -0600783 {
784 rfBpLastState = "BusInitializationStarted";
785 }
George Liu0fda0f12021-11-16 10:06:17 +0800786 else if (
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700787 bootProgressStr ==
George Liu0fda0f12021-11-16 10:06:17 +0800788 "xyz.openbmc_project.State.Boot.Progress.ProgressStages.MemoryInit")
Andrew Geissler978b8802020-11-19 13:36:40 -0600789 {
790 rfBpLastState = "MemoryInitializationStarted";
791 }
George Liu0fda0f12021-11-16 10:06:17 +0800792 else if (
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700793 bootProgressStr ==
George Liu0fda0f12021-11-16 10:06:17 +0800794 "xyz.openbmc_project.State.Boot.Progress.ProgressStages.SecondaryProcInit")
Andrew Geissler978b8802020-11-19 13:36:40 -0600795 {
796 rfBpLastState = "SecondaryProcessorInitializationStarted";
797 }
George Liu0fda0f12021-11-16 10:06:17 +0800798 else if (
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700799 bootProgressStr ==
George Liu0fda0f12021-11-16 10:06:17 +0800800 "xyz.openbmc_project.State.Boot.Progress.ProgressStages.PCIInit")
Andrew Geissler978b8802020-11-19 13:36:40 -0600801 {
802 rfBpLastState = "PCIResourceConfigStarted";
803 }
George Liu0fda0f12021-11-16 10:06:17 +0800804 else if (
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700805 bootProgressStr ==
Andrew Geissler9ec65ef2022-01-05 09:44:13 -0600806 "xyz.openbmc_project.State.Boot.Progress.ProgressStages.SystemSetup")
807 {
808 rfBpLastState = "SetupEntered";
809 }
810 else if (
811 bootProgressStr ==
George Liu0fda0f12021-11-16 10:06:17 +0800812 "xyz.openbmc_project.State.Boot.Progress.ProgressStages.SystemInitComplete")
Andrew Geissler978b8802020-11-19 13:36:40 -0600813 {
814 rfBpLastState = "SystemHardwareInitializationComplete";
815 }
George Liu0fda0f12021-11-16 10:06:17 +0800816 else if (
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700817 bootProgressStr ==
George Liu0fda0f12021-11-16 10:06:17 +0800818 "xyz.openbmc_project.State.Boot.Progress.ProgressStages.OSStart")
Andrew Geissler978b8802020-11-19 13:36:40 -0600819 {
820 rfBpLastState = "OSBootStarted";
821 }
George Liu0fda0f12021-11-16 10:06:17 +0800822 else if (
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700823 bootProgressStr ==
George Liu0fda0f12021-11-16 10:06:17 +0800824 "xyz.openbmc_project.State.Boot.Progress.ProgressStages.OSRunning")
Andrew Geissler978b8802020-11-19 13:36:40 -0600825 {
826 rfBpLastState = "OSRunning";
827 }
828 else
829 {
830 BMCWEB_LOG_DEBUG << "Unsupported D-Bus BootProgress "
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700831 << bootProgressStr;
Andrew Geissler978b8802020-11-19 13:36:40 -0600832 // Just return the default
833 }
834
835 aResp->res.jsonValue["BootProgress"]["LastState"] = rfBpLastState;
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700836 });
Andrew Geissler978b8802020-11-19 13:36:40 -0600837}
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530838
839/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300840 * @brief Retrieves boot override type over DBUS and fills out the response
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300841 *
842 * @param[in] aResp Shared pointer for generating response message.
843 *
844 * @return None.
845 */
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300846
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300847inline void getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300848{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700849 sdbusplus::asio::getProperty<std::string>(
850 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
851 "/xyz/openbmc_project/control/host0/boot",
852 "xyz.openbmc_project.Control.Boot.Type", "BootType",
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300853 [aResp](const boost::system::error_code ec,
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700854 const std::string& bootType) {
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300855 if (ec)
856 {
857 // not an error, don't have to have the interface
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300858 return;
859 }
860
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700861 BMCWEB_LOG_DEBUG << "Boot type: " << bootType;
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300862
George Liu0fda0f12021-11-16 10:06:17 +0800863 aResp->res
864 .jsonValue["Boot"]
865 ["BootSourceOverrideMode@Redfish.AllowableValues"] = {
866 "Legacy", "UEFI"};
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300867
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700868 auto rfType = dbusToRfBootType(bootType);
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300869 if (rfType.empty())
870 {
871 messages::internalError(aResp->res);
872 return;
873 }
874
875 aResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType;
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700876 });
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300877}
878
879/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300880 * @brief Retrieves boot override mode over DBUS and fills out the response
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530881 *
882 * @param[in] aResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530883 *
884 * @return None.
885 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300886
887inline void getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530888{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700889 sdbusplus::asio::getProperty<std::string>(
890 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
891 "/xyz/openbmc_project/control/host0/boot",
892 "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300893 [aResp](const boost::system::error_code ec,
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700894 const std::string& bootModeStr) {
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530895 if (ec)
896 {
897 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
898 messages::internalError(aResp->res);
899 return;
900 }
901
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700902 BMCWEB_LOG_DEBUG << "Boot mode: " << bootModeStr;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530903
George Liu0fda0f12021-11-16 10:06:17 +0800904 aResp->res
905 .jsonValue["Boot"]
906 ["BootSourceOverrideTarget@Redfish.AllowableValues"] =
907 {"None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530908
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700909 if (bootModeStr !=
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530910 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
911 {
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700912 auto rfMode = dbusToRfBootMode(bootModeStr);
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530913 if (!rfMode.empty())
914 {
915 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
916 rfMode;
917 }
918 }
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700919 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530920}
921
922/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300923 * @brief Retrieves boot override source over DBUS
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530924 *
925 * @param[in] aResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530926 *
927 * @return None.
928 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300929
930inline void
931 getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530932{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700933 sdbusplus::asio::getProperty<std::string>(
934 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
935 "/xyz/openbmc_project/control/host0/boot",
936 "xyz.openbmc_project.Control.Boot.Source", "BootSource",
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300937 [aResp](const boost::system::error_code ec,
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700938 const std::string& bootSourceStr) {
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530939 if (ec)
940 {
941 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
942 messages::internalError(aResp->res);
943 return;
944 }
945
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700946 BMCWEB_LOG_DEBUG << "Boot source: " << bootSourceStr;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530947
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700948 auto rfSource = dbusToRfBootSource(bootSourceStr);
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530949 if (!rfSource.empty())
950 {
951 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
952 rfSource;
953 }
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300954
955 // Get BootMode as BootSourceOverrideTarget is constructed
956 // from both BootSource and BootMode
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300957 getBootOverrideMode(aResp);
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700958 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530959}
960
961/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300962 * @brief This functions abstracts all the logic behind getting a
963 * "BootSourceOverrideEnabled" property from an overall boot override enable
964 * state
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530965 *
966 * @param[in] aResp Shared pointer for generating response message.
967 *
968 * @return None.
969 */
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530970
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300971inline void
972 processBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
973 const bool bootOverrideEnableSetting)
974{
975 if (!bootOverrideEnableSetting)
976 {
977 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = "Disabled";
978 return;
979 }
980
981 // If boot source override is enabled, we need to check 'one_time'
982 // property to set a correct value for the "BootSourceOverrideEnabled"
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700983 sdbusplus::asio::getProperty<bool>(
984 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
985 "/xyz/openbmc_project/control/host0/boot/one_time",
986 "xyz.openbmc_project.Object.Enable", "Enabled",
987 [aResp](const boost::system::error_code ec, bool oneTimeSetting) {
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530988 if (ec)
989 {
990 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300991 messages::internalError(aResp->res);
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530992 return;
993 }
994
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300995 if (oneTimeSetting)
996 {
997 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
998 "Once";
999 }
1000 else
1001 {
1002 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1003 "Continuous";
1004 }
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001005 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301006}
1007
1008/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001009 * @brief Retrieves boot override enable over DBUS
1010 *
1011 * @param[in] aResp Shared pointer for generating response message.
1012 *
1013 * @return None.
1014 */
1015
1016inline void
1017 getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1018{
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001019 sdbusplus::asio::getProperty<bool>(
1020 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1021 "/xyz/openbmc_project/control/host0/boot",
1022 "xyz.openbmc_project.Object.Enable", "Enabled",
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001023 [aResp](const boost::system::error_code ec,
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001024 const bool bootOverrideEnable) {
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001025 if (ec)
1026 {
1027 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1028 messages::internalError(aResp->res);
1029 return;
1030 }
1031
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001032 processBootOverrideEnable(aResp, bootOverrideEnable);
1033 });
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001034}
1035
1036/**
1037 * @brief Retrieves boot source override properties
1038 *
1039 * @param[in] aResp Shared pointer for generating response message.
1040 *
1041 * @return None.
1042 */
1043inline void getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1044{
1045 BMCWEB_LOG_DEBUG << "Get boot information.";
1046
1047 getBootOverrideSource(aResp);
1048 getBootOverrideType(aResp);
1049 getBootOverrideEnable(aResp);
1050}
1051
1052/**
Gunnar Millsc0557e12020-06-30 11:26:20 -05001053 * @brief Retrieves the Last Reset Time
1054 *
1055 * "Reset" is an overloaded term in Redfish, "Reset" includes power on
1056 * and power off. Even though this is the "system" Redfish object look at the
1057 * chassis D-Bus interface for the LastStateChangeTime since this has the
1058 * last power operation time.
1059 *
1060 * @param[in] aResp Shared pointer for generating response message.
1061 *
1062 * @return None.
1063 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001064inline void getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
Gunnar Millsc0557e12020-06-30 11:26:20 -05001065{
1066 BMCWEB_LOG_DEBUG << "Getting System Last Reset Time";
1067
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001068 sdbusplus::asio::getProperty<uint64_t>(
1069 *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
1070 "/xyz/openbmc_project/state/chassis0",
1071 "xyz.openbmc_project.State.Chassis", "LastStateChangeTime",
1072 [aResp](const boost::system::error_code ec, uint64_t lastResetTime) {
Gunnar Millsc0557e12020-06-30 11:26:20 -05001073 if (ec)
1074 {
1075 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
1076 return;
1077 }
1078
Gunnar Millsc0557e12020-06-30 11:26:20 -05001079 // LastStateChangeTime is epoch time, in milliseconds
1080 // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001081 uint64_t lastResetTimeStamp = lastResetTime / 1000;
Gunnar Millsc0557e12020-06-30 11:26:20 -05001082
1083 // Convert to ISO 8601 standard
1084 aResp->res.jsonValue["LastResetTime"] =
Nan Zhou1d8782e2021-11-29 22:23:18 -08001085 crow::utility::getDateTimeUint(lastResetTimeStamp);
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001086 });
Gunnar Millsc0557e12020-06-30 11:26:20 -05001087}
1088
1089/**
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001090 * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
1091 *
1092 * @param[in] aResp Shared pointer for generating response message.
1093 *
1094 * @return None.
1095 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001096inline void getAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001097{
1098 BMCWEB_LOG_DEBUG << "Get Automatic Retry policy";
1099
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001100 sdbusplus::asio::getProperty<bool>(
1101 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1102 "/xyz/openbmc_project/control/host0/auto_reboot",
1103 "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
1104 [aResp](const boost::system::error_code ec, bool autoRebootEnabled) {
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001105 if (ec)
1106 {
1107 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
1108 return;
1109 }
1110
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001111 BMCWEB_LOG_DEBUG << "Auto Reboot: " << autoRebootEnabled;
1112 if (autoRebootEnabled == true)
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001113 {
1114 aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
1115 "RetryAttempts";
1116 // If AutomaticRetry (AutoReboot) is enabled see how many
1117 // attempts are left
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001118 sdbusplus::asio::getProperty<uint32_t>(
1119 *crow::connections::systemBus,
1120 "xyz.openbmc_project.State.Host",
1121 "/xyz/openbmc_project/state/host0",
1122 "xyz.openbmc_project.Control.Boot.RebootAttempts",
1123 "AttemptsLeft",
Ed Tanouscb13a392020-07-25 19:02:03 +00001124 [aResp](const boost::system::error_code ec2,
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001125 uint32_t autoRebootAttemptsLeft) {
Ed Tanouscb13a392020-07-25 19:02:03 +00001126 if (ec2)
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001127 {
Ed Tanouscb13a392020-07-25 19:02:03 +00001128 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec2;
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001129 return;
1130 }
1131
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001132 BMCWEB_LOG_DEBUG << "Auto Reboot Attempts Left: "
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001133 << autoRebootAttemptsLeft;
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001134
1135 aResp->res
1136 .jsonValue["Boot"]
1137 ["RemainingAutomaticRetryAttempts"] =
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001138 autoRebootAttemptsLeft;
1139 });
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001140 }
1141 else
1142 {
1143 aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
1144 "Disabled";
1145 }
1146
1147 // Not on D-Bus. Hardcoded here:
1148 // https://github.com/openbmc/phosphor-state-manager/blob/1dbbef42675e94fb1f78edb87d6b11380260535a/meson_options.txt#L71
1149 aResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] = 3;
Gunnar Mills69f35302020-05-17 16:06:31 -05001150
1151 // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
1152 // and RetryAttempts. OpenBMC only supports Disabled and
1153 // RetryAttempts.
George Liu0fda0f12021-11-16 10:06:17 +08001154 aResp->res
1155 .jsonValue["Boot"]
1156 ["AutomaticRetryConfig@Redfish.AllowableValues"] = {
1157 "Disabled", "RetryAttempts"};
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001158 });
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001159}
1160
1161/**
George Liuc6a620f2020-04-10 17:18:11 +08001162 * @brief Retrieves power restore policy over DBUS.
1163 *
1164 * @param[in] aResp Shared pointer for generating response message.
1165 *
1166 * @return None.
1167 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001168inline void
1169 getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
George Liuc6a620f2020-04-10 17:18:11 +08001170{
1171 BMCWEB_LOG_DEBUG << "Get power restore policy";
1172
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001173 sdbusplus::asio::getProperty<std::string>(
1174 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1175 "/xyz/openbmc_project/control/host0/power_restore_policy",
1176 "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
1177 [aResp](const boost::system::error_code ec, const std::string& policy) {
George Liuc6a620f2020-04-10 17:18:11 +08001178 if (ec)
1179 {
1180 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1181 return;
1182 }
1183
George Liu0fda0f12021-11-16 10:06:17 +08001184 const boost::container::flat_map<std::string, std::string> policyMaps = {
1185 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn",
1186 "AlwaysOn"},
1187 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff",
1188 "AlwaysOff"},
1189 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore",
1190 "LastState"}};
George Liuc6a620f2020-04-10 17:18:11 +08001191
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001192 auto policyMapsIt = policyMaps.find(policy);
George Liuc6a620f2020-04-10 17:18:11 +08001193 if (policyMapsIt == policyMaps.end())
1194 {
1195 messages::internalError(aResp->res);
1196 return;
1197 }
1198
1199 aResp->res.jsonValue["PowerRestorePolicy"] = policyMapsIt->second;
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001200 });
George Liuc6a620f2020-04-10 17:18:11 +08001201}
1202
1203/**
Ali Ahmed19817712021-06-29 17:01:52 -05001204 * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not
1205 * TPM is required for booting the host.
1206 *
1207 * @param[in] aResp Shared pointer for generating response message.
1208 *
1209 * @return None.
1210 */
1211inline void getTrustedModuleRequiredToBoot(
1212 const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1213{
1214 BMCWEB_LOG_DEBUG << "Get TPM required to boot.";
1215
1216 crow::connections::systemBus->async_method_call(
1217 [aResp](
1218 const boost::system::error_code ec,
1219 std::vector<std::pair<
1220 std::string,
1221 std::vector<std::pair<std::string, std::vector<std::string>>>>>&
1222 subtree) {
1223 if (ec)
1224 {
1225 BMCWEB_LOG_DEBUG
1226 << "DBUS response error on TPM.Policy GetSubTree" << ec;
1227 // This is an optional D-Bus object so just return if
1228 // error occurs
1229 return;
1230 }
1231 if (subtree.size() == 0)
1232 {
1233 // As noted above, this is an optional interface so just return
1234 // if there is no instance found
1235 return;
1236 }
1237
1238 /* When there is more than one TPMEnable object... */
1239 if (subtree.size() > 1)
1240 {
1241 BMCWEB_LOG_DEBUG
1242 << "DBUS response has more than 1 TPM Enable object:"
1243 << subtree.size();
1244 // Throw an internal Error and return
1245 messages::internalError(aResp->res);
1246 return;
1247 }
1248
1249 // Make sure the Dbus response map has a service and objectPath
1250 // field
1251 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1252 {
1253 BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
1254 messages::internalError(aResp->res);
1255 return;
1256 }
1257
1258 const std::string& path = subtree[0].first;
1259 const std::string& serv = subtree[0].second.begin()->first;
1260
1261 // Valid TPM Enable object found, now reading the current value
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001262 sdbusplus::asio::getProperty<bool>(
1263 *crow::connections::systemBus, serv, path,
1264 "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
1265 [aResp](const boost::system::error_code ec, bool tpmRequired) {
Ali Ahmed19817712021-06-29 17:01:52 -05001266 if (ec)
1267 {
1268 BMCWEB_LOG_DEBUG
1269 << "D-BUS response error on TPM.Policy Get" << ec;
1270 messages::internalError(aResp->res);
1271 return;
1272 }
1273
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001274 if (tpmRequired)
Ali Ahmed19817712021-06-29 17:01:52 -05001275 {
1276 aResp->res
1277 .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
1278 "Required";
1279 }
1280 else
1281 {
1282 aResp->res
1283 .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
1284 "Disabled";
1285 }
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001286 });
Ali Ahmed19817712021-06-29 17:01:52 -05001287 },
1288 "xyz.openbmc_project.ObjectMapper",
1289 "/xyz/openbmc_project/object_mapper",
1290 "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
1291 std::array<const char*, 1>{"xyz.openbmc_project.Control.TPM.Policy"});
1292}
1293
1294/**
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001295 * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not
1296 * TPM is required for booting the host.
1297 *
1298 * @param[in] aResp Shared pointer for generating response message.
1299 * @param[in] tpmRequired Value to set TPM Required To Boot property to.
1300 *
1301 * @return None.
1302 */
1303inline void setTrustedModuleRequiredToBoot(
1304 const std::shared_ptr<bmcweb::AsyncResp>& aResp, const bool tpmRequired)
1305{
1306 BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot.";
1307
1308 crow::connections::systemBus->async_method_call(
1309 [aResp, tpmRequired](
1310 const boost::system::error_code ec,
1311 std::vector<std::pair<
1312 std::string,
1313 std::vector<std::pair<std::string, std::vector<std::string>>>>>&
1314 subtree) {
1315 if (ec)
1316 {
1317 BMCWEB_LOG_DEBUG
1318 << "DBUS response error on TPM.Policy GetSubTree" << ec;
1319 messages::internalError(aResp->res);
1320 return;
1321 }
1322 if (subtree.size() == 0)
1323 {
1324 messages::propertyValueNotInList(aResp->res, "ComputerSystem",
1325 "TrustedModuleRequiredToBoot");
1326 return;
1327 }
1328
1329 /* When there is more than one TPMEnable object... */
1330 if (subtree.size() > 1)
1331 {
1332 BMCWEB_LOG_DEBUG
1333 << "DBUS response has more than 1 TPM Enable object:"
1334 << subtree.size();
1335 // Throw an internal Error and return
1336 messages::internalError(aResp->res);
1337 return;
1338 }
1339
1340 // Make sure the Dbus response map has a service and objectPath
1341 // field
1342 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1343 {
1344 BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
1345 messages::internalError(aResp->res);
1346 return;
1347 }
1348
1349 const std::string& path = subtree[0].first;
1350 const std::string& serv = subtree[0].second.begin()->first;
1351
1352 if (serv.empty())
1353 {
1354 BMCWEB_LOG_DEBUG << "TPM.Policy service mapper error!";
1355 messages::internalError(aResp->res);
1356 return;
1357 }
1358
1359 // Valid TPM Enable object found, now setting the value
1360 crow::connections::systemBus->async_method_call(
1361 [aResp](const boost::system::error_code ec) {
1362 if (ec)
1363 {
George Liu0fda0f12021-11-16 10:06:17 +08001364 BMCWEB_LOG_DEBUG
1365 << "DBUS response error: Set TrustedModuleRequiredToBoot"
1366 << ec;
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001367 messages::internalError(aResp->res);
1368 return;
1369 }
1370 BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot done.";
1371 },
1372 serv, path, "org.freedesktop.DBus.Properties", "Set",
1373 "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
Ed Tanous168e20c2021-12-13 14:39:53 -08001374 dbus::utility::DbusVariantType(tpmRequired));
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001375 },
1376 "xyz.openbmc_project.ObjectMapper",
1377 "/xyz/openbmc_project/object_mapper",
1378 "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
1379 std::array<const char*, 1>{"xyz.openbmc_project.Control.TPM.Policy"});
1380}
1381
1382/**
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301383 * @brief Sets boot properties into DBUS object(s).
1384 *
1385 * @param[in] aResp Shared pointer for generating response message.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001386 * @param[in] bootType The boot type to set.
1387 * @return Integer error code.
1388 */
1389inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001390 const std::optional<std::string>& bootType)
1391{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001392 std::string bootTypeStr;
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001393
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001394 if (!bootType)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001395 {
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001396 return;
1397 }
1398
1399 // Source target specified
1400 BMCWEB_LOG_DEBUG << "Boot type: " << *bootType;
1401 // Figure out which DBUS interface and property to use
1402 if (*bootType == "Legacy")
1403 {
1404 bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy";
1405 }
1406 else if (*bootType == "UEFI")
1407 {
1408 bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI";
1409 }
1410 else
1411 {
1412 BMCWEB_LOG_DEBUG << "Invalid property value for "
1413 "BootSourceOverrideMode: "
1414 << *bootType;
1415 messages::propertyValueNotInList(aResp->res, *bootType,
1416 "BootSourceOverrideMode");
1417 return;
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001418 }
1419
1420 // Act on validated parameters
1421 BMCWEB_LOG_DEBUG << "DBUS boot type: " << bootTypeStr;
1422
1423 crow::connections::systemBus->async_method_call(
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001424 [aResp](const boost::system::error_code ec) {
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001425 if (ec)
1426 {
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001427 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1428 if (ec.value() == boost::asio::error::host_unreachable)
1429 {
1430 messages::resourceNotFound(aResp->res, "Set", "BootType");
1431 return;
1432 }
1433 messages::internalError(aResp->res);
1434 return;
1435 }
1436 BMCWEB_LOG_DEBUG << "Boot type update done.";
1437 },
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001438 "xyz.openbmc_project.Settings",
1439 "/xyz/openbmc_project/control/host0/boot",
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001440 "org.freedesktop.DBus.Properties", "Set",
1441 "xyz.openbmc_project.Control.Boot.Type", "BootType",
Ed Tanous168e20c2021-12-13 14:39:53 -08001442 dbus::utility::DbusVariantType(bootTypeStr));
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001443}
1444
1445/**
1446 * @brief Sets boot properties into DBUS object(s).
1447 *
1448 * @param[in] aResp Shared pointer for generating response message.
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001449 * @param[in] bootType The boot type to set.
1450 * @return Integer error code.
1451 */
1452inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1453 const std::optional<std::string>& bootEnable)
1454{
1455 if (!bootEnable)
1456 {
1457 return;
1458 }
1459 // Source target specified
1460 BMCWEB_LOG_DEBUG << "Boot enable: " << *bootEnable;
1461
1462 bool bootOverrideEnable = false;
1463 bool bootOverridePersistent = false;
1464 // Figure out which DBUS interface and property to use
1465 if (*bootEnable == "Disabled")
1466 {
1467 bootOverrideEnable = false;
1468 }
1469 else if (*bootEnable == "Once")
1470 {
1471 bootOverrideEnable = true;
1472 bootOverridePersistent = false;
1473 }
1474 else if (*bootEnable == "Continuous")
1475 {
1476 bootOverrideEnable = true;
1477 bootOverridePersistent = true;
1478 }
1479 else
1480 {
George Liu0fda0f12021-11-16 10:06:17 +08001481 BMCWEB_LOG_DEBUG
1482 << "Invalid property value for BootSourceOverrideEnabled: "
1483 << *bootEnable;
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001484 messages::propertyValueNotInList(aResp->res, *bootEnable,
1485 "BootSourceOverrideEnabled");
1486 return;
1487 }
1488
1489 // Act on validated parameters
1490 BMCWEB_LOG_DEBUG << "DBUS boot override enable: " << bootOverrideEnable;
1491
1492 crow::connections::systemBus->async_method_call(
1493 [aResp](const boost::system::error_code ec) {
1494 if (ec)
1495 {
1496 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1497 messages::internalError(aResp->res);
1498 return;
1499 }
1500 BMCWEB_LOG_DEBUG << "Boot override enable update done.";
1501 },
1502 "xyz.openbmc_project.Settings",
1503 "/xyz/openbmc_project/control/host0/boot",
1504 "org.freedesktop.DBus.Properties", "Set",
1505 "xyz.openbmc_project.Object.Enable", "Enabled",
Ed Tanous168e20c2021-12-13 14:39:53 -08001506 dbus::utility::DbusVariantType(bootOverrideEnable));
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001507
1508 if (!bootOverrideEnable)
1509 {
1510 return;
1511 }
1512
1513 // In case boot override is enabled we need to set correct value for the
1514 // 'one_time' enable DBus interface
1515 BMCWEB_LOG_DEBUG << "DBUS boot override persistent: "
1516 << bootOverridePersistent;
1517
1518 crow::connections::systemBus->async_method_call(
1519 [aResp](const boost::system::error_code ec) {
1520 if (ec)
1521 {
1522 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1523 messages::internalError(aResp->res);
1524 return;
1525 }
1526 BMCWEB_LOG_DEBUG << "Boot one_time update done.";
1527 },
1528 "xyz.openbmc_project.Settings",
1529 "/xyz/openbmc_project/control/host0/boot/one_time",
1530 "org.freedesktop.DBus.Properties", "Set",
1531 "xyz.openbmc_project.Object.Enable", "Enabled",
Ed Tanous168e20c2021-12-13 14:39:53 -08001532 dbus::utility::DbusVariantType(!bootOverridePersistent));
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001533}
1534
1535/**
1536 * @brief Sets boot properties into DBUS object(s).
1537 *
1538 * @param[in] aResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301539 * @param[in] bootSource The boot source to set.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301540 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001541 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301542 */
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001543inline void setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001544 const std::optional<std::string>& bootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301545{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001546 std::string bootSourceStr;
1547 std::string bootModeStr;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001548
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001549 if (!bootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301550 {
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001551 return;
1552 }
1553
1554 // Source target specified
1555 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource;
1556 // Figure out which DBUS interface and property to use
1557 if (assignBootParameters(aResp, *bootSource, bootSourceStr, bootModeStr))
1558 {
1559 BMCWEB_LOG_DEBUG
1560 << "Invalid property value for BootSourceOverrideTarget: "
1561 << *bootSource;
1562 messages::propertyValueNotInList(aResp->res, *bootSource,
1563 "BootSourceTargetOverride");
1564 return;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001565 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301566
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001567 // Act on validated parameters
1568 BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
1569 BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001570
1571 crow::connections::systemBus->async_method_call(
1572 [aResp](const boost::system::error_code ec) {
1573 if (ec)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301574 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001575 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1576 messages::internalError(aResp->res);
1577 return;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301578 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001579 BMCWEB_LOG_DEBUG << "Boot source update done.";
1580 },
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001581 "xyz.openbmc_project.Settings",
1582 "/xyz/openbmc_project/control/host0/boot",
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001583 "org.freedesktop.DBus.Properties", "Set",
1584 "xyz.openbmc_project.Control.Boot.Source", "BootSource",
Ed Tanous168e20c2021-12-13 14:39:53 -08001585 dbus::utility::DbusVariantType(bootSourceStr));
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001586
1587 crow::connections::systemBus->async_method_call(
1588 [aResp](const boost::system::error_code ec) {
1589 if (ec)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301590 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001591 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1592 messages::internalError(aResp->res);
1593 return;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301594 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001595 BMCWEB_LOG_DEBUG << "Boot mode update done.";
1596 },
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001597 "xyz.openbmc_project.Settings",
1598 "/xyz/openbmc_project/control/host0/boot",
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001599 "org.freedesktop.DBus.Properties", "Set",
1600 "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
Ed Tanous168e20c2021-12-13 14:39:53 -08001601 dbus::utility::DbusVariantType(bootModeStr));
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001602}
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001603
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001604/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001605 * @brief Sets Boot source override properties.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301606 *
1607 * @param[in] aResp Shared pointer for generating response message.
1608 * @param[in] bootSource The boot source from incoming RF request.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001609 * @param[in] bootType The boot type from incoming RF request.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301610 * @param[in] bootEnable The boot override enable from incoming RF request.
1611 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001612 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301613 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001614
1615inline void setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1616 const std::optional<std::string>& bootSource,
1617 const std::optional<std::string>& bootType,
1618 const std::optional<std::string>& bootEnable)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301619{
1620 BMCWEB_LOG_DEBUG << "Set boot information.";
1621
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001622 setBootModeOrSource(aResp, bootSource);
1623 setBootType(aResp, bootType);
1624 setBootEnable(aResp, bootEnable);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301625}
1626
George Liuc6a620f2020-04-10 17:18:11 +08001627/**
Gunnar Mills98e386e2020-10-30 14:58:09 -05001628 * @brief Sets AssetTag
1629 *
1630 * @param[in] aResp Shared pointer for generating response message.
1631 * @param[in] assetTag "AssetTag" from request.
1632 *
1633 * @return None.
1634 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001635inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Gunnar Mills98e386e2020-10-30 14:58:09 -05001636 const std::string& assetTag)
1637{
1638 crow::connections::systemBus->async_method_call(
1639 [aResp, assetTag](
1640 const boost::system::error_code ec,
1641 const std::vector<std::pair<
1642 std::string,
1643 std::vector<std::pair<std::string, std::vector<std::string>>>>>&
1644 subtree) {
1645 if (ec)
1646 {
1647 BMCWEB_LOG_DEBUG << "D-Bus response error on GetSubTree " << ec;
1648 messages::internalError(aResp->res);
1649 return;
1650 }
1651 if (subtree.size() == 0)
1652 {
1653 BMCWEB_LOG_DEBUG << "Can't find system D-Bus object!";
1654 messages::internalError(aResp->res);
1655 return;
1656 }
1657 // Assume only 1 system D-Bus object
1658 // Throw an error if there is more than 1
1659 if (subtree.size() > 1)
1660 {
1661 BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus object!";
1662 messages::internalError(aResp->res);
1663 return;
1664 }
1665 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1666 {
1667 BMCWEB_LOG_DEBUG << "Asset Tag Set mapper error!";
1668 messages::internalError(aResp->res);
1669 return;
1670 }
1671
1672 const std::string& path = subtree[0].first;
1673 const std::string& service = subtree[0].second.begin()->first;
1674
1675 if (service.empty())
1676 {
1677 BMCWEB_LOG_DEBUG << "Asset Tag Set service mapper error!";
1678 messages::internalError(aResp->res);
1679 return;
1680 }
1681
1682 crow::connections::systemBus->async_method_call(
1683 [aResp](const boost::system::error_code ec2) {
1684 if (ec2)
1685 {
1686 BMCWEB_LOG_DEBUG
1687 << "D-Bus response error on AssetTag Set " << ec2;
1688 messages::internalError(aResp->res);
1689 return;
1690 }
1691 },
1692 service, path, "org.freedesktop.DBus.Properties", "Set",
1693 "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag",
Ed Tanous168e20c2021-12-13 14:39:53 -08001694 dbus::utility::DbusVariantType(assetTag));
Gunnar Mills98e386e2020-10-30 14:58:09 -05001695 },
1696 "xyz.openbmc_project.ObjectMapper",
1697 "/xyz/openbmc_project/object_mapper",
1698 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
1699 "/xyz/openbmc_project/inventory", int32_t(0),
1700 std::array<const char*, 1>{
1701 "xyz.openbmc_project.Inventory.Item.System"});
1702}
1703
1704/**
Gunnar Mills69f35302020-05-17 16:06:31 -05001705 * @brief Sets automaticRetry (Auto Reboot)
1706 *
1707 * @param[in] aResp Shared pointer for generating response message.
1708 * @param[in] automaticRetryConfig "AutomaticRetryConfig" from request.
1709 *
1710 * @return None.
1711 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001712inline void setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Ed Tanousf23b7292020-10-15 09:41:17 -07001713 const std::string& automaticRetryConfig)
Gunnar Mills69f35302020-05-17 16:06:31 -05001714{
1715 BMCWEB_LOG_DEBUG << "Set Automatic Retry.";
1716
1717 // OpenBMC only supports "Disabled" and "RetryAttempts".
1718 bool autoRebootEnabled;
1719
1720 if (automaticRetryConfig == "Disabled")
1721 {
1722 autoRebootEnabled = false;
1723 }
1724 else if (automaticRetryConfig == "RetryAttempts")
1725 {
1726 autoRebootEnabled = true;
1727 }
1728 else
1729 {
George Liu0fda0f12021-11-16 10:06:17 +08001730 BMCWEB_LOG_DEBUG << "Invalid property value for AutomaticRetryConfig: "
Gunnar Mills69f35302020-05-17 16:06:31 -05001731 << automaticRetryConfig;
1732 messages::propertyValueNotInList(aResp->res, automaticRetryConfig,
1733 "AutomaticRetryConfig");
1734 return;
1735 }
1736
1737 crow::connections::systemBus->async_method_call(
1738 [aResp](const boost::system::error_code ec) {
1739 if (ec)
1740 {
1741 messages::internalError(aResp->res);
1742 return;
1743 }
1744 },
1745 "xyz.openbmc_project.Settings",
1746 "/xyz/openbmc_project/control/host0/auto_reboot",
1747 "org.freedesktop.DBus.Properties", "Set",
1748 "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
Ed Tanous168e20c2021-12-13 14:39:53 -08001749 dbus::utility::DbusVariantType(autoRebootEnabled));
Gunnar Mills69f35302020-05-17 16:06:31 -05001750}
1751
1752/**
George Liuc6a620f2020-04-10 17:18:11 +08001753 * @brief Sets power restore policy properties.
1754 *
1755 * @param[in] aResp Shared pointer for generating response message.
1756 * @param[in] policy power restore policy properties from request.
1757 *
1758 * @return None.
1759 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001760inline void
1761 setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1762 const std::string& policy)
George Liuc6a620f2020-04-10 17:18:11 +08001763{
1764 BMCWEB_LOG_DEBUG << "Set power restore policy.";
1765
1766 const boost::container::flat_map<std::string, std::string> policyMaps = {
George Liu0fda0f12021-11-16 10:06:17 +08001767 {"AlwaysOn",
1768 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn"},
1769 {"AlwaysOff",
1770 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff"},
1771 {"LastState",
1772 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore"}};
George Liuc6a620f2020-04-10 17:18:11 +08001773
1774 std::string powerRestorPolicy;
1775
Gunnar Mills4e69c902021-01-05 19:50:11 -06001776 auto policyMapsIt = policyMaps.find(policy);
George Liuc6a620f2020-04-10 17:18:11 +08001777 if (policyMapsIt == policyMaps.end())
1778 {
Gunnar Mills4e69c902021-01-05 19:50:11 -06001779 messages::propertyValueNotInList(aResp->res, policy,
1780 "PowerRestorePolicy");
George Liuc6a620f2020-04-10 17:18:11 +08001781 return;
1782 }
1783
1784 powerRestorPolicy = policyMapsIt->second;
1785
1786 crow::connections::systemBus->async_method_call(
1787 [aResp](const boost::system::error_code ec) {
1788 if (ec)
1789 {
1790 messages::internalError(aResp->res);
1791 return;
1792 }
1793 },
1794 "xyz.openbmc_project.Settings",
1795 "/xyz/openbmc_project/control/host0/power_restore_policy",
1796 "org.freedesktop.DBus.Properties", "Set",
1797 "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
Ed Tanous168e20c2021-12-13 14:39:53 -08001798 dbus::utility::DbusVariantType(powerRestorPolicy));
George Liuc6a620f2020-04-10 17:18:11 +08001799}
1800
AppaRao Pulia6349912019-10-18 17:16:08 +05301801#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1802/**
1803 * @brief Retrieves provisioning status
1804 *
1805 * @param[in] aResp Shared pointer for completing asynchronous calls.
1806 *
1807 * @return None.
1808 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001809inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> aResp)
AppaRao Pulia6349912019-10-18 17:16:08 +05301810{
1811 BMCWEB_LOG_DEBUG << "Get OEM information.";
1812 crow::connections::systemBus->async_method_call(
1813 [aResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001814 const std::vector<std::pair<std::string, VariantType>>&
1815 propertiesList) {
AppaRao Pulib99fb1a2020-07-08 16:42:48 +05301816 nlohmann::json& oemPFR =
1817 aResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
James Feist50626f42020-09-23 14:40:47 -07001818 aResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
1819 "#OemComputerSystem.OpenBmc";
1820 oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning";
1821
AppaRao Pulia6349912019-10-18 17:16:08 +05301822 if (ec)
1823 {
1824 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
AppaRao Pulib99fb1a2020-07-08 16:42:48 +05301825 // not an error, don't have to have the interface
1826 oemPFR["ProvisioningStatus"] = "NotProvisioned";
AppaRao Pulia6349912019-10-18 17:16:08 +05301827 return;
1828 }
1829
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001830 const bool* provState = nullptr;
1831 const bool* lockState = nullptr;
1832 for (const std::pair<std::string, VariantType>& property :
AppaRao Pulia6349912019-10-18 17:16:08 +05301833 propertiesList)
1834 {
1835 if (property.first == "UfmProvisioned")
1836 {
1837 provState = std::get_if<bool>(&property.second);
1838 }
1839 else if (property.first == "UfmLocked")
1840 {
1841 lockState = std::get_if<bool>(&property.second);
1842 }
1843 }
1844
1845 if ((provState == nullptr) || (lockState == nullptr))
1846 {
1847 BMCWEB_LOG_DEBUG << "Unable to get PFR attributes.";
1848 messages::internalError(aResp->res);
1849 return;
1850 }
1851
AppaRao Pulia6349912019-10-18 17:16:08 +05301852 if (*provState == true)
1853 {
1854 if (*lockState == true)
1855 {
1856 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
1857 }
1858 else
1859 {
1860 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
1861 }
1862 }
1863 else
1864 {
1865 oemPFR["ProvisioningStatus"] = "NotProvisioned";
1866 }
1867 },
1868 "xyz.openbmc_project.PFR.Manager", "/xyz/openbmc_project/pfr",
1869 "org.freedesktop.DBus.Properties", "GetAll",
1870 "xyz.openbmc_project.PFR.Attributes");
1871}
1872#endif
1873
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301874/**
Chris Cain3a2d04242021-05-28 16:57:10 -05001875 * @brief Translate the PowerMode to a response message.
1876 *
1877 * @param[in] aResp Shared pointer for generating response message.
1878 * @param[in] modeValue PowerMode value to be translated
1879 *
1880 * @return None.
1881 */
1882inline void translatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1883 const std::string& modeValue)
1884{
1885 std::string modeString;
1886
George Liu0fda0f12021-11-16 10:06:17 +08001887 if (modeValue == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static")
Chris Cain3a2d04242021-05-28 16:57:10 -05001888 {
1889 aResp->res.jsonValue["PowerMode"] = "Static";
1890 }
George Liu0fda0f12021-11-16 10:06:17 +08001891 else if (
1892 modeValue ==
1893 "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance")
Chris Cain3a2d04242021-05-28 16:57:10 -05001894 {
1895 aResp->res.jsonValue["PowerMode"] = "MaximumPerformance";
1896 }
George Liu0fda0f12021-11-16 10:06:17 +08001897 else if (modeValue ==
1898 "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving")
Chris Cain3a2d04242021-05-28 16:57:10 -05001899 {
1900 aResp->res.jsonValue["PowerMode"] = "PowerSaving";
1901 }
George Liu0fda0f12021-11-16 10:06:17 +08001902 else if (modeValue ==
1903 "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM")
Chris Cain3a2d04242021-05-28 16:57:10 -05001904 {
1905 aResp->res.jsonValue["PowerMode"] = "OEM";
1906 }
1907 else
1908 {
1909 // Any other values would be invalid
1910 BMCWEB_LOG_DEBUG << "PowerMode value was not valid: " << modeValue;
1911 messages::internalError(aResp->res);
1912 }
1913}
1914
1915/**
1916 * @brief Retrieves system power mode
1917 *
1918 * @param[in] aResp Shared pointer for generating response message.
1919 *
1920 * @return None.
1921 */
1922inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1923{
1924 BMCWEB_LOG_DEBUG << "Get power mode.";
1925
1926 // Get Power Mode object path:
1927 crow::connections::systemBus->async_method_call(
1928 [aResp](
1929 const boost::system::error_code ec,
1930 const std::vector<std::pair<
1931 std::string,
1932 std::vector<std::pair<std::string, std::vector<std::string>>>>>&
1933 subtree) {
1934 if (ec)
1935 {
1936 BMCWEB_LOG_DEBUG
1937 << "DBUS response error on Power.Mode GetSubTree " << ec;
1938 // This is an optional D-Bus object so just return if
1939 // error occurs
1940 return;
1941 }
1942 if (subtree.empty())
1943 {
1944 // As noted above, this is an optional interface so just return
1945 // if there is no instance found
1946 return;
1947 }
1948 if (subtree.size() > 1)
1949 {
1950 // More then one PowerMode object is not supported and is an
1951 // error
1952 BMCWEB_LOG_DEBUG
1953 << "Found more than 1 system D-Bus Power.Mode objects: "
1954 << subtree.size();
1955 messages::internalError(aResp->res);
1956 return;
1957 }
1958 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
1959 {
1960 BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
1961 messages::internalError(aResp->res);
1962 return;
1963 }
1964 const std::string& path = subtree[0].first;
1965 const std::string& service = subtree[0].second.begin()->first;
1966 if (service.empty())
1967 {
1968 BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
1969 messages::internalError(aResp->res);
1970 return;
1971 }
1972 // Valid Power Mode object found, now read the current value
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001973 sdbusplus::asio::getProperty<std::string>(
1974 *crow::connections::systemBus, service, path,
1975 "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
Chris Cain3a2d04242021-05-28 16:57:10 -05001976 [aResp](const boost::system::error_code ec,
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001977 const std::string& pmode) {
Chris Cain3a2d04242021-05-28 16:57:10 -05001978 if (ec)
1979 {
1980 BMCWEB_LOG_DEBUG
1981 << "DBUS response error on PowerMode Get: " << ec;
1982 messages::internalError(aResp->res);
1983 return;
1984 }
1985
Chris Cain3a2d04242021-05-28 16:57:10 -05001986 aResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] =
1987 {"Static", "MaximumPerformance", "PowerSaving"};
1988
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001989 BMCWEB_LOG_DEBUG << "Current power mode: " << pmode;
1990 translatePowerMode(aResp, pmode);
1991 });
Chris Cain3a2d04242021-05-28 16:57:10 -05001992 },
1993 "xyz.openbmc_project.ObjectMapper",
1994 "/xyz/openbmc_project/object_mapper",
1995 "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
1996 std::array<const char*, 1>{"xyz.openbmc_project.Control.Power.Mode"});
1997}
1998
1999/**
2000 * @brief Validate the specified mode is valid and return the PowerMode
2001 * name associated with that string
2002 *
2003 * @param[in] aResp Shared pointer for generating response message.
2004 * @param[in] modeString String representing the desired PowerMode
2005 *
2006 * @return PowerMode value or empty string if mode is not valid
2007 */
2008inline std::string
2009 validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
2010 const std::string& modeString)
2011{
2012 std::string mode;
2013
2014 if (modeString == "Static")
2015 {
2016 mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static";
2017 }
2018 else if (modeString == "MaximumPerformance")
2019 {
George Liu0fda0f12021-11-16 10:06:17 +08002020 mode =
2021 "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance";
Chris Cain3a2d04242021-05-28 16:57:10 -05002022 }
2023 else if (modeString == "PowerSaving")
2024 {
2025 mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving";
2026 }
2027 else
2028 {
2029 messages::propertyValueNotInList(aResp->res, modeString, "PowerMode");
2030 }
2031 return mode;
2032}
2033
2034/**
2035 * @brief Sets system power mode.
2036 *
2037 * @param[in] aResp Shared pointer for generating response message.
2038 * @param[in] pmode System power mode from request.
2039 *
2040 * @return None.
2041 */
2042inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
2043 const std::string& pmode)
2044{
2045 BMCWEB_LOG_DEBUG << "Set power mode.";
2046
2047 std::string powerMode = validatePowerMode(aResp, pmode);
2048 if (powerMode.empty())
2049 {
2050 return;
2051 }
2052
2053 // Get Power Mode object path:
2054 crow::connections::systemBus->async_method_call(
2055 [aResp, powerMode](
2056 const boost::system::error_code ec,
2057 const std::vector<std::pair<
2058 std::string,
2059 std::vector<std::pair<std::string, std::vector<std::string>>>>>&
2060 subtree) {
2061 if (ec)
2062 {
2063 BMCWEB_LOG_DEBUG
2064 << "DBUS response error on Power.Mode GetSubTree " << ec;
2065 // This is an optional D-Bus object, but user attempted to patch
2066 messages::internalError(aResp->res);
2067 return;
2068 }
2069 if (subtree.empty())
2070 {
2071 // This is an optional D-Bus object, but user attempted to patch
2072 messages::resourceNotFound(aResp->res, "ComputerSystem",
2073 "PowerMode");
2074 return;
2075 }
2076 if (subtree.size() > 1)
2077 {
2078 // More then one PowerMode object is not supported and is an
2079 // error
2080 BMCWEB_LOG_DEBUG
2081 << "Found more than 1 system D-Bus Power.Mode objects: "
2082 << subtree.size();
2083 messages::internalError(aResp->res);
2084 return;
2085 }
2086 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2087 {
2088 BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
2089 messages::internalError(aResp->res);
2090 return;
2091 }
2092 const std::string& path = subtree[0].first;
2093 const std::string& service = subtree[0].second.begin()->first;
2094 if (service.empty())
2095 {
2096 BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
2097 messages::internalError(aResp->res);
2098 return;
2099 }
2100
2101 BMCWEB_LOG_DEBUG << "Setting power mode(" << powerMode << ") -> "
2102 << path;
2103
2104 // Set the Power Mode property
2105 crow::connections::systemBus->async_method_call(
2106 [aResp](const boost::system::error_code ec) {
2107 if (ec)
2108 {
2109 messages::internalError(aResp->res);
2110 return;
2111 }
2112 },
2113 service, path, "org.freedesktop.DBus.Properties", "Set",
2114 "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
Ed Tanous168e20c2021-12-13 14:39:53 -08002115 dbus::utility::DbusVariantType(powerMode));
Chris Cain3a2d04242021-05-28 16:57:10 -05002116 },
2117 "xyz.openbmc_project.ObjectMapper",
2118 "/xyz/openbmc_project/object_mapper",
2119 "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
2120 std::array<const char*, 1>{"xyz.openbmc_project.Control.Power.Mode"});
2121}
2122
2123/**
Yong Li51709ff2019-09-30 14:13:04 +08002124 * @brief Translates watchdog timeout action DBUS property value to redfish.
2125 *
2126 * @param[in] dbusAction The watchdog timeout action in D-BUS.
2127 *
2128 * @return Returns as a string, the timeout action in Redfish terms. If
2129 * translation cannot be done, returns an empty string.
2130 */
Ed Tanous23a21a12020-07-25 04:45:05 +00002131inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
Yong Li51709ff2019-09-30 14:13:04 +08002132{
2133 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
2134 {
2135 return "None";
2136 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002137 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
Yong Li51709ff2019-09-30 14:13:04 +08002138 {
2139 return "ResetSystem";
2140 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002141 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
Yong Li51709ff2019-09-30 14:13:04 +08002142 {
2143 return "PowerDown";
2144 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002145 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
Yong Li51709ff2019-09-30 14:13:04 +08002146 {
2147 return "PowerCycle";
2148 }
2149
2150 return "";
2151}
2152
2153/**
Yong Lic45f0082019-10-10 14:19:01 +08002154 *@brief Translates timeout action from Redfish to DBUS property value.
2155 *
2156 *@param[in] rfAction The timeout action in Redfish.
2157 *
2158 *@return Returns as a string, the time_out action as expected by DBUS.
2159 *If translation cannot be done, returns an empty string.
2160 */
2161
Ed Tanous23a21a12020-07-25 04:45:05 +00002162inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
Yong Lic45f0082019-10-10 14:19:01 +08002163{
2164 if (rfAction == "None")
2165 {
2166 return "xyz.openbmc_project.State.Watchdog.Action.None";
2167 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002168 if (rfAction == "PowerCycle")
Yong Lic45f0082019-10-10 14:19:01 +08002169 {
2170 return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
2171 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002172 if (rfAction == "PowerDown")
Yong Lic45f0082019-10-10 14:19:01 +08002173 {
2174 return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
2175 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002176 if (rfAction == "ResetSystem")
Yong Lic45f0082019-10-10 14:19:01 +08002177 {
2178 return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
2179 }
2180
2181 return "";
2182}
2183
2184/**
Yong Li51709ff2019-09-30 14:13:04 +08002185 * @brief Retrieves host watchdog timer properties over DBUS
2186 *
2187 * @param[in] aResp Shared pointer for completing asynchronous calls.
2188 *
2189 * @return None.
2190 */
zhanghch058d1b46d2021-04-01 11:18:24 +08002191inline void
2192 getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
Yong Li51709ff2019-09-30 14:13:04 +08002193{
2194 BMCWEB_LOG_DEBUG << "Get host watchodg";
2195 crow::connections::systemBus->async_method_call(
2196 [aResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05002197 PropertiesType& properties) {
Yong Li51709ff2019-09-30 14:13:04 +08002198 if (ec)
2199 {
2200 // watchdog service is stopped
2201 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2202 return;
2203 }
2204
2205 BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop.";
2206
Gunnar Mills1214b7e2020-06-04 10:11:30 -05002207 nlohmann::json& hostWatchdogTimer =
Yong Li51709ff2019-09-30 14:13:04 +08002208 aResp->res.jsonValue["HostWatchdogTimer"];
2209
2210 // watchdog service is running/enabled
2211 hostWatchdogTimer["Status"]["State"] = "Enabled";
2212
Gunnar Mills1214b7e2020-06-04 10:11:30 -05002213 for (const auto& property : properties)
Yong Li51709ff2019-09-30 14:13:04 +08002214 {
2215 BMCWEB_LOG_DEBUG << "prop=" << property.first;
2216 if (property.first == "Enabled")
2217 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -05002218 const bool* state = std::get_if<bool>(&property.second);
Yong Li51709ff2019-09-30 14:13:04 +08002219
2220 if (!state)
2221 {
2222 messages::internalError(aResp->res);
Chicago Duan601af5e2021-04-15 16:59:25 +08002223 return;
Yong Li51709ff2019-09-30 14:13:04 +08002224 }
2225
2226 hostWatchdogTimer["FunctionEnabled"] = *state;
2227 }
2228 else if (property.first == "ExpireAction")
2229 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -05002230 const std::string* s =
Yong Li51709ff2019-09-30 14:13:04 +08002231 std::get_if<std::string>(&property.second);
2232 if (!s)
2233 {
2234 messages::internalError(aResp->res);
Chicago Duan601af5e2021-04-15 16:59:25 +08002235 return;
Yong Li51709ff2019-09-30 14:13:04 +08002236 }
2237
2238 std::string action = dbusToRfWatchdogAction(*s);
2239 if (action.empty())
2240 {
2241 messages::internalError(aResp->res);
Chicago Duan601af5e2021-04-15 16:59:25 +08002242 return;
Yong Li51709ff2019-09-30 14:13:04 +08002243 }
2244 hostWatchdogTimer["TimeoutAction"] = action;
2245 }
2246 }
2247 },
2248 "xyz.openbmc_project.Watchdog", "/xyz/openbmc_project/watchdog/host0",
2249 "org.freedesktop.DBus.Properties", "GetAll",
2250 "xyz.openbmc_project.State.Watchdog");
2251}
2252
2253/**
Yong Lic45f0082019-10-10 14:19:01 +08002254 * @brief Sets Host WatchDog Timer properties.
2255 *
2256 * @param[in] aResp Shared pointer for generating response message.
2257 * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming
2258 * RF request.
2259 * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
2260 *
2261 * @return None.
2262 */
zhanghch058d1b46d2021-04-01 11:18:24 +08002263inline void setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Yong Lic45f0082019-10-10 14:19:01 +08002264 const std::optional<bool> wdtEnable,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05002265 const std::optional<std::string>& wdtTimeOutAction)
Yong Lic45f0082019-10-10 14:19:01 +08002266{
2267 BMCWEB_LOG_DEBUG << "Set host watchdog";
2268
2269 if (wdtTimeOutAction)
2270 {
2271 std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
2272 // check if TimeOut Action is Valid
2273 if (wdtTimeOutActStr.empty())
2274 {
2275 BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: "
2276 << *wdtTimeOutAction;
2277 messages::propertyValueNotInList(aResp->res, *wdtTimeOutAction,
2278 "TimeoutAction");
2279 return;
2280 }
2281
2282 crow::connections::systemBus->async_method_call(
2283 [aResp](const boost::system::error_code ec) {
2284 if (ec)
2285 {
2286 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2287 messages::internalError(aResp->res);
2288 return;
2289 }
2290 },
2291 "xyz.openbmc_project.Watchdog",
2292 "/xyz/openbmc_project/watchdog/host0",
2293 "org.freedesktop.DBus.Properties", "Set",
2294 "xyz.openbmc_project.State.Watchdog", "ExpireAction",
Ed Tanous168e20c2021-12-13 14:39:53 -08002295 dbus::utility::DbusVariantType(wdtTimeOutActStr));
Yong Lic45f0082019-10-10 14:19:01 +08002296 }
2297
2298 if (wdtEnable)
2299 {
2300 crow::connections::systemBus->async_method_call(
2301 [aResp](const boost::system::error_code ec) {
2302 if (ec)
2303 {
2304 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2305 messages::internalError(aResp->res);
2306 return;
2307 }
2308 },
2309 "xyz.openbmc_project.Watchdog",
2310 "/xyz/openbmc_project/watchdog/host0",
2311 "org.freedesktop.DBus.Properties", "Set",
2312 "xyz.openbmc_project.State.Watchdog", "Enabled",
Ed Tanous168e20c2021-12-13 14:39:53 -08002313 dbus::utility::DbusVariantType(*wdtEnable));
Yong Lic45f0082019-10-10 14:19:01 +08002314 }
2315}
2316
Chris Cain37bbf982021-09-20 10:53:09 -05002317using ipsPropertiesType =
2318 std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>;
2319/**
2320 * @brief Parse the Idle Power Saver properties into json
2321 *
2322 * @param[in] aResp Shared pointer for completing asynchronous calls.
2323 * @param[in] properties IPS property data from DBus.
2324 *
2325 * @return true if successful
2326 */
Ed Tanousf6674222021-11-13 09:41:41 -08002327inline bool parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
2328 ipsPropertiesType& properties)
Chris Cain37bbf982021-09-20 10:53:09 -05002329{
2330 for (const auto& property : properties)
2331 {
2332 if (property.first == "Enabled")
2333 {
2334 const bool* state = std::get_if<bool>(&property.second);
2335 if (!state)
2336 {
2337 return false;
2338 }
2339 aResp->res.jsonValue["IdlePowerSaver"][property.first] = *state;
2340 }
2341 else if (property.first == "EnterUtilizationPercent")
2342 {
2343 const uint8_t* util = std::get_if<uint8_t>(&property.second);
2344 if (!util)
2345 {
2346 return false;
2347 }
2348 aResp->res.jsonValue["IdlePowerSaver"][property.first] = *util;
2349 }
2350 else if (property.first == "EnterDwellTime")
2351 {
2352 // Convert Dbus time from milliseconds to seconds
2353 const uint64_t* timeMilliseconds =
2354 std::get_if<uint64_t>(&property.second);
2355 if (!timeMilliseconds)
2356 {
2357 return false;
2358 }
2359 const std::chrono::duration<uint64_t, std::milli> ms(
2360 *timeMilliseconds);
2361 aResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] =
2362 std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
2363 .count();
2364 }
2365 else if (property.first == "ExitUtilizationPercent")
2366 {
2367 const uint8_t* util = std::get_if<uint8_t>(&property.second);
2368 if (!util)
2369 {
2370 return false;
2371 }
2372 aResp->res.jsonValue["IdlePowerSaver"][property.first] = *util;
2373 }
2374 else if (property.first == "ExitDwellTime")
2375 {
2376 // Convert Dbus time from milliseconds to seconds
2377 const uint64_t* timeMilliseconds =
2378 std::get_if<uint64_t>(&property.second);
2379 if (!timeMilliseconds)
2380 {
2381 return false;
2382 }
2383 const std::chrono::duration<uint64_t, std::milli> ms(
2384 *timeMilliseconds);
2385 aResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] =
2386 std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
2387 .count();
2388 }
2389 else
2390 {
2391 BMCWEB_LOG_WARNING << "Unexpected IdlePowerSaver property: "
2392 << property.first;
2393 }
2394 }
2395
2396 return true;
2397}
2398
2399/**
2400 * @brief Retrieves host watchdog timer properties over DBUS
2401 *
2402 * @param[in] aResp Shared pointer for completing asynchronous calls.
2403 *
2404 * @return None.
2405 */
2406inline void getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
2407{
2408 BMCWEB_LOG_DEBUG << "Get idle power saver parameters";
2409
2410 // Get IdlePowerSaver object path:
2411 crow::connections::systemBus->async_method_call(
2412 [aResp](
2413 const boost::system::error_code ec,
2414 const std::vector<std::pair<
2415 std::string,
2416 std::vector<std::pair<std::string, std::vector<std::string>>>>>&
2417 subtree) {
2418 if (ec)
2419 {
2420 BMCWEB_LOG_DEBUG
2421 << "DBUS response error on Power.IdlePowerSaver GetSubTree "
2422 << ec;
2423 messages::internalError(aResp->res);
2424 return;
2425 }
2426 if (subtree.empty())
2427 {
2428 // This is an optional interface so just return
2429 // if there is no instance found
2430 BMCWEB_LOG_DEBUG << "No instances found";
2431 return;
2432 }
2433 if (subtree.size() > 1)
2434 {
2435 // More then one PowerIdlePowerSaver object is not supported and
2436 // is an error
2437 BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus "
2438 "Power.IdlePowerSaver objects: "
2439 << subtree.size();
2440 messages::internalError(aResp->res);
2441 return;
2442 }
2443 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2444 {
2445 BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!";
2446 messages::internalError(aResp->res);
2447 return;
2448 }
2449 const std::string& path = subtree[0].first;
2450 const std::string& service = subtree[0].second.begin()->first;
2451 if (service.empty())
2452 {
2453 BMCWEB_LOG_DEBUG
2454 << "Power.IdlePowerSaver service mapper error!";
2455 messages::internalError(aResp->res);
2456 return;
2457 }
2458
2459 // Valid IdlePowerSaver object found, now read the current values
2460 crow::connections::systemBus->async_method_call(
2461 [aResp](const boost::system::error_code ec,
2462 ipsPropertiesType& properties) {
2463 if (ec)
2464 {
2465 BMCWEB_LOG_ERROR
2466 << "DBUS response error on IdlePowerSaver GetAll: "
2467 << ec;
2468 messages::internalError(aResp->res);
2469 return;
2470 }
2471
2472 if (parseIpsProperties(aResp, properties) == false)
2473 {
2474 messages::internalError(aResp->res);
2475 return;
2476 }
2477 },
2478 service, path, "org.freedesktop.DBus.Properties", "GetAll",
2479 "xyz.openbmc_project.Control.Power.IdlePowerSaver");
2480 },
2481 "xyz.openbmc_project.ObjectMapper",
2482 "/xyz/openbmc_project/object_mapper",
2483 "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
2484 std::array<const char*, 1>{
2485 "xyz.openbmc_project.Control.Power.IdlePowerSaver"});
2486
2487 BMCWEB_LOG_DEBUG << "EXIT: Get idle power saver parameters";
2488}
2489
2490/**
2491 * @brief Sets Idle Power Saver properties.
2492 *
2493 * @param[in] aResp Shared pointer for generating response message.
2494 * @param[in] ipsEnable The IPS Enable value (true/false) from incoming
2495 * RF request.
2496 * @param[in] ipsEnterUtil The utilization limit to enter idle state.
2497 * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil
2498 * before entering idle state.
2499 * @param[in] ipsExitUtil The utilization limit when exiting idle state.
2500 * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil
2501 * before exiting idle state
2502 *
2503 * @return None.
2504 */
2505inline void setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
2506 const std::optional<bool> ipsEnable,
2507 const std::optional<uint8_t> ipsEnterUtil,
2508 const std::optional<uint64_t> ipsEnterTime,
2509 const std::optional<uint8_t> ipsExitUtil,
2510 const std::optional<uint64_t> ipsExitTime)
2511{
2512 BMCWEB_LOG_DEBUG << "Set idle power saver properties";
2513
2514 // Get IdlePowerSaver object path:
2515 crow::connections::systemBus->async_method_call(
2516 [aResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil,
2517 ipsExitTime](
2518 const boost::system::error_code ec,
2519 const std::vector<std::pair<
2520 std::string,
2521 std::vector<std::pair<std::string, std::vector<std::string>>>>>&
2522 subtree) {
2523 if (ec)
2524 {
2525 BMCWEB_LOG_DEBUG
2526 << "DBUS response error on Power.IdlePowerSaver GetSubTree "
2527 << ec;
2528 messages::internalError(aResp->res);
2529 return;
2530 }
2531 if (subtree.empty())
2532 {
2533 // This is an optional D-Bus object, but user attempted to patch
2534 messages::resourceNotFound(aResp->res, "ComputerSystem",
2535 "IdlePowerSaver");
2536 return;
2537 }
2538 if (subtree.size() > 1)
2539 {
2540 // More then one PowerIdlePowerSaver object is not supported and
2541 // is an error
George Liu0fda0f12021-11-16 10:06:17 +08002542 BMCWEB_LOG_DEBUG
2543 << "Found more than 1 system D-Bus Power.IdlePowerSaver objects: "
2544 << subtree.size();
Chris Cain37bbf982021-09-20 10:53:09 -05002545 messages::internalError(aResp->res);
2546 return;
2547 }
2548 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2549 {
2550 BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!";
2551 messages::internalError(aResp->res);
2552 return;
2553 }
2554 const std::string& path = subtree[0].first;
2555 const std::string& service = subtree[0].second.begin()->first;
2556 if (service.empty())
2557 {
2558 BMCWEB_LOG_DEBUG
2559 << "Power.IdlePowerSaver service mapper error!";
2560 messages::internalError(aResp->res);
2561 return;
2562 }
2563
2564 // Valid Power IdlePowerSaver object found, now set any values that
2565 // need to be updated
2566
2567 if (ipsEnable)
2568 {
2569 crow::connections::systemBus->async_method_call(
2570 [aResp](const boost::system::error_code ec) {
2571 if (ec)
2572 {
2573 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2574 messages::internalError(aResp->res);
2575 return;
2576 }
2577 },
2578 service, path, "org.freedesktop.DBus.Properties", "Set",
2579 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
Ed Tanous168e20c2021-12-13 14:39:53 -08002580 "Enabled", dbus::utility::DbusVariantType(*ipsEnable));
Chris Cain37bbf982021-09-20 10:53:09 -05002581 }
2582 if (ipsEnterUtil)
2583 {
2584 crow::connections::systemBus->async_method_call(
2585 [aResp](const boost::system::error_code ec) {
2586 if (ec)
2587 {
2588 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2589 messages::internalError(aResp->res);
2590 return;
2591 }
2592 },
2593 service, path, "org.freedesktop.DBus.Properties", "Set",
2594 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2595 "EnterUtilizationPercent",
Ed Tanous168e20c2021-12-13 14:39:53 -08002596 dbus::utility::DbusVariantType(*ipsEnterUtil));
Chris Cain37bbf982021-09-20 10:53:09 -05002597 }
2598 if (ipsEnterTime)
2599 {
2600 // Convert from seconds into milliseconds for DBus
2601 const uint64_t timeMilliseconds = *ipsEnterTime * 1000;
2602 crow::connections::systemBus->async_method_call(
2603 [aResp](const boost::system::error_code ec) {
2604 if (ec)
2605 {
2606 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2607 messages::internalError(aResp->res);
2608 return;
2609 }
2610 },
2611 service, path, "org.freedesktop.DBus.Properties", "Set",
2612 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
Ed Tanous168e20c2021-12-13 14:39:53 -08002613 "EnterDwellTime",
2614 dbus::utility::DbusVariantType(timeMilliseconds));
Chris Cain37bbf982021-09-20 10:53:09 -05002615 }
2616 if (ipsExitUtil)
2617 {
2618 crow::connections::systemBus->async_method_call(
2619 [aResp](const boost::system::error_code ec) {
2620 if (ec)
2621 {
2622 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2623 messages::internalError(aResp->res);
2624 return;
2625 }
2626 },
2627 service, path, "org.freedesktop.DBus.Properties", "Set",
2628 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2629 "ExitUtilizationPercent",
Ed Tanous168e20c2021-12-13 14:39:53 -08002630 dbus::utility::DbusVariantType(*ipsExitUtil));
Chris Cain37bbf982021-09-20 10:53:09 -05002631 }
2632 if (ipsExitTime)
2633 {
2634 // Convert from seconds into milliseconds for DBus
2635 const uint64_t timeMilliseconds = *ipsExitTime * 1000;
2636 crow::connections::systemBus->async_method_call(
2637 [aResp](const boost::system::error_code ec) {
2638 if (ec)
2639 {
2640 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2641 messages::internalError(aResp->res);
2642 return;
2643 }
2644 },
2645 service, path, "org.freedesktop.DBus.Properties", "Set",
2646 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
Ed Tanous168e20c2021-12-13 14:39:53 -08002647 "ExitDwellTime",
2648 dbus::utility::DbusVariantType(timeMilliseconds));
Chris Cain37bbf982021-09-20 10:53:09 -05002649 }
2650 },
2651 "xyz.openbmc_project.ObjectMapper",
2652 "/xyz/openbmc_project/object_mapper",
2653 "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
2654 std::array<const char*, 1>{
2655 "xyz.openbmc_project.Control.Power.IdlePowerSaver"});
2656
2657 BMCWEB_LOG_DEBUG << "EXIT: Set idle power saver parameters";
2658}
2659
Yong Lic45f0082019-10-10 14:19:01 +08002660/**
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002661 * SystemsCollection derived class for delivering ComputerSystems Collection
2662 * Schema
2663 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002664inline void requestRoutesSystemsCollection(App& app)
Ed Tanous1abe55e2018-09-05 08:30:59 -07002665{
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002666 BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
Ed Tanoused398212021-06-09 17:05:54 -07002667 .privileges(redfish::privileges::getComputerSystemCollection)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002668 .methods(boost::beast::http::verb::get)(
Ed Tanous4f48d5f2021-06-21 08:27:45 -07002669 [](const crow::Request& /*req*/,
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002670 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
2671 asyncResp->res.jsonValue["@odata.type"] =
2672 "#ComputerSystemCollection.ComputerSystemCollection";
2673 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
2674 asyncResp->res.jsonValue["Name"] = "Computer System Collection";
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002675
Jonathan Doman1e1e5982021-06-11 09:36:17 -07002676 sdbusplus::asio::getProperty<std::string>(
2677 *crow::connections::systemBus,
2678 "xyz.openbmc_project.Settings",
2679 "/xyz/openbmc_project/network/hypervisor",
2680 "xyz.openbmc_project.Network.SystemConfiguration",
2681 "HostName",
2682 [asyncResp](const boost::system::error_code ec,
2683 const std::string& /*hostName*/) {
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002684 nlohmann::json& ifaceArray =
2685 asyncResp->res.jsonValue["Members"];
2686 ifaceArray = nlohmann::json::array();
2687 auto& count =
2688 asyncResp->res.jsonValue["Members@odata.count"];
2689 ifaceArray.push_back(
2690 {{"@odata.id", "/redfish/v1/Systems/system"}});
2691 count = ifaceArray.size();
2692 if (!ec)
2693 {
2694 BMCWEB_LOG_DEBUG << "Hypervisor is available";
2695 ifaceArray.push_back(
2696 {{"@odata.id",
2697 "/redfish/v1/Systems/hypervisor"}});
2698 count = ifaceArray.size();
2699 }
Jonathan Doman1e1e5982021-06-11 09:36:17 -07002700 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002701 });
2702}
Sunitha Harish462023a2020-02-19 08:34:59 -06002703
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002704/**
2705 * Function transceives data with dbus directly.
2706 */
Ed Tanous4f48d5f2021-06-21 08:27:45 -07002707inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002708{
2709 constexpr char const* serviceName = "xyz.openbmc_project.Control.Host.NMI";
2710 constexpr char const* objectPath = "/xyz/openbmc_project/control/host0/nmi";
2711 constexpr char const* interfaceName =
2712 "xyz.openbmc_project.Control.Host.NMI";
2713 constexpr char const* method = "NMI";
2714
2715 crow::connections::systemBus->async_method_call(
2716 [asyncResp](const boost::system::error_code ec) {
2717 if (ec)
2718 {
2719 BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
2720 messages::internalError(asyncResp->res);
2721 return;
2722 }
2723 messages::success(asyncResp->res);
2724 },
2725 serviceName, objectPath, interfaceName, method);
2726}
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002727
2728/**
Ed Tanouscc340dd2018-08-29 13:43:38 -07002729 * SystemActionsReset class supports handle POST method for Reset action.
2730 * The class retrieves and sends data directly to D-Bus.
2731 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002732inline void requestRoutesSystemActionsReset(App& app)
Ed Tanouscc340dd2018-08-29 13:43:38 -07002733{
Ed Tanouscc340dd2018-08-29 13:43:38 -07002734 /**
2735 * Function handles POST method request.
2736 * Analyzes POST body message before sends Reset request data to D-Bus.
2737 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002738 BMCWEB_ROUTE(app,
2739 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/")
Ed Tanoused398212021-06-09 17:05:54 -07002740 .privileges(redfish::privileges::postComputerSystem)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002741 .methods(
2742 boost::beast::http::verb::
2743 post)([](const crow::Request& req,
2744 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
2745 std::string resetType;
2746 if (!json_util::readJson(req, asyncResp->res, "ResetType",
2747 resetType))
2748 {
2749 return;
2750 }
Ed Tanous9712f8a2018-09-21 13:38:49 -07002751
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002752 // Get the command and host vs. chassis
2753 std::string command;
2754 bool hostCommand;
2755 if ((resetType == "On") || (resetType == "ForceOn"))
2756 {
2757 command = "xyz.openbmc_project.State.Host.Transition.On";
2758 hostCommand = true;
2759 }
2760 else if (resetType == "ForceOff")
2761 {
2762 command = "xyz.openbmc_project.State.Chassis.Transition.Off";
2763 hostCommand = false;
2764 }
2765 else if (resetType == "ForceRestart")
2766 {
2767 command =
2768 "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
2769 hostCommand = true;
2770 }
2771 else if (resetType == "GracefulShutdown")
2772 {
2773 command = "xyz.openbmc_project.State.Host.Transition.Off";
2774 hostCommand = true;
2775 }
2776 else if (resetType == "GracefulRestart")
2777 {
George Liu0fda0f12021-11-16 10:06:17 +08002778 command =
2779 "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002780 hostCommand = true;
2781 }
2782 else if (resetType == "PowerCycle")
2783 {
2784 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
2785 hostCommand = true;
2786 }
2787 else if (resetType == "Nmi")
2788 {
2789 doNMI(asyncResp);
2790 return;
2791 }
2792 else
2793 {
2794 messages::actionParameterUnknown(asyncResp->res, "Reset",
2795 resetType);
2796 return;
2797 }
Ed Tanouscc340dd2018-08-29 13:43:38 -07002798
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002799 if (hostCommand)
2800 {
2801 crow::connections::systemBus->async_method_call(
2802 [asyncResp, resetType](const boost::system::error_code ec) {
2803 if (ec)
Jason M. Billsd22c8392019-06-03 13:59:03 -07002804 {
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002805 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
2806 if (ec.value() ==
2807 boost::asio::error::invalid_argument)
2808 {
2809 messages::actionParameterNotSupported(
2810 asyncResp->res, resetType, "Reset");
2811 }
2812 else
2813 {
2814 messages::internalError(asyncResp->res);
2815 }
2816 return;
Jason M. Billsd22c8392019-06-03 13:59:03 -07002817 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002818 messages::success(asyncResp->res);
2819 },
2820 "xyz.openbmc_project.State.Host",
2821 "/xyz/openbmc_project/state/host0",
2822 "org.freedesktop.DBus.Properties", "Set",
2823 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
Ed Tanous168e20c2021-12-13 14:39:53 -08002824 dbus::utility::DbusVariantType{command});
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002825 }
2826 else
2827 {
2828 crow::connections::systemBus->async_method_call(
2829 [asyncResp, resetType](const boost::system::error_code ec) {
2830 if (ec)
Jason M. Billsd22c8392019-06-03 13:59:03 -07002831 {
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002832 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
2833 if (ec.value() ==
2834 boost::asio::error::invalid_argument)
2835 {
2836 messages::actionParameterNotSupported(
2837 asyncResp->res, resetType, "Reset");
2838 }
2839 else
2840 {
2841 messages::internalError(asyncResp->res);
2842 }
2843 return;
Jason M. Billsd22c8392019-06-03 13:59:03 -07002844 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002845 messages::success(asyncResp->res);
2846 },
2847 "xyz.openbmc_project.State.Chassis",
2848 "/xyz/openbmc_project/state/chassis0",
2849 "org.freedesktop.DBus.Properties", "Set",
2850 "xyz.openbmc_project.State.Chassis",
2851 "RequestedPowerTransition",
Ed Tanous168e20c2021-12-13 14:39:53 -08002852 dbus::utility::DbusVariantType{command});
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002853 }
2854 });
2855}
Ed Tanouscc340dd2018-08-29 13:43:38 -07002856
2857/**
Ed Tanous66173382018-08-15 18:20:59 -07002858 * Systems derived class for delivering Computer Systems Schema.
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002859 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002860inline void requestRoutesSystems(App& app)
Ed Tanous1abe55e2018-09-05 08:30:59 -07002861{
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002862
Ed Tanous1abe55e2018-09-05 08:30:59 -07002863 /**
2864 * Functions triggers appropriate requests on DBus
2865 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002866 BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/")
Ed Tanoused398212021-06-09 17:05:54 -07002867 .privileges(redfish::privileges::getComputerSystem)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002868 .methods(
2869 boost::beast::http::verb::
2870 get)([](const crow::Request&,
2871 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
2872 asyncResp->res.jsonValue["@odata.type"] =
Chris Cain37bbf982021-09-20 10:53:09 -05002873 "#ComputerSystem.v1_16_0.ComputerSystem";
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002874 asyncResp->res.jsonValue["Name"] = "system";
2875 asyncResp->res.jsonValue["Id"] = "system";
2876 asyncResp->res.jsonValue["SystemType"] = "Physical";
2877 asyncResp->res.jsonValue["Description"] = "Computer System";
2878 asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
2879 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
2880 "Disabled";
2881 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
2882 uint64_t(0);
2883 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
2884 "Disabled";
2885 asyncResp->res.jsonValue["@odata.id"] =
2886 "/redfish/v1/Systems/system";
Ed Tanous04a258f2018-10-15 08:00:41 -07002887
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002888 asyncResp->res.jsonValue["Processors"] = {
2889 {"@odata.id", "/redfish/v1/Systems/system/Processors"}};
2890 asyncResp->res.jsonValue["Memory"] = {
2891 {"@odata.id", "/redfish/v1/Systems/system/Memory"}};
2892 asyncResp->res.jsonValue["Storage"] = {
2893 {"@odata.id", "/redfish/v1/Systems/system/Storage"}};
Ed Tanous029573d2019-02-01 10:57:49 -08002894
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002895 asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"] = {
2896 {"target",
2897 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"},
2898 {"@Redfish.ActionInfo",
2899 "/redfish/v1/Systems/system/ResetActionInfo"}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002900
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002901 asyncResp->res.jsonValue["LogServices"] = {
2902 {"@odata.id", "/redfish/v1/Systems/system/LogServices"}};
Jason M. Billsc4bf6372018-11-05 13:48:27 -08002903
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002904 asyncResp->res.jsonValue["Bios"] = {
2905 {"@odata.id", "/redfish/v1/Systems/system/Bios"}};
Carol Wangd82a3ac2019-11-21 13:56:38 +08002906
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002907 asyncResp->res.jsonValue["Links"]["ManagedBy"] = {
2908 {{"@odata.id", "/redfish/v1/Managers/bmc"}}};
Jennifer Leec5d03ff2019-03-08 15:42:58 -08002909
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002910 asyncResp->res.jsonValue["Status"] = {
2911 {"Health", "OK"},
2912 {"State", "Enabled"},
2913 };
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06002914
2915 // Fill in SerialConsole info
2916 asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] =
2917 15;
2918 asyncResp->res.jsonValue["SerialConsole"]["IPMI"] = {
2919 {"ServiceEnabled", true},
2920 };
2921 // TODO (Gunnar): Should look for obmc-console-ssh@2200.service
2922 asyncResp->res.jsonValue["SerialConsole"]["SSH"] = {
2923 {"ServiceEnabled", true},
2924 {"Port", 2200},
2925 // https://github.com/openbmc/docs/blob/master/console.md
2926 {"HotKeySequenceDisplay", "Press ~. to exit console"},
2927 };
2928
2929#ifdef BMCWEB_ENABLE_KVM
2930 // Fill in GraphicalConsole info
2931 asyncResp->res.jsonValue["GraphicalConsole"] = {
2932 {"ServiceEnabled", true},
2933 {"MaxConcurrentSessions", 4},
2934 {"ConnectTypesSupported", {"KVMIP"}},
2935 };
2936#endif // BMCWEB_ENABLE_KVM
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002937 constexpr const std::array<const char*, 4> inventoryForSystems = {
2938 "xyz.openbmc_project.Inventory.Item.Dimm",
2939 "xyz.openbmc_project.Inventory.Item.Cpu",
2940 "xyz.openbmc_project.Inventory.Item.Drive",
2941 "xyz.openbmc_project.Inventory.Item.StorageController"};
James Feistb49ac872019-05-21 15:12:01 -07002942
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002943 auto health = std::make_shared<HealthPopulate>(asyncResp);
2944 crow::connections::systemBus->async_method_call(
2945 [health](const boost::system::error_code ec,
2946 std::vector<std::string>& resp) {
2947 if (ec)
2948 {
2949 // no inventory
2950 return;
2951 }
2952
2953 health->inventory = std::move(resp);
2954 },
2955 "xyz.openbmc_project.ObjectMapper",
2956 "/xyz/openbmc_project/object_mapper",
2957 "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", "/",
2958 int32_t(0), inventoryForSystems);
2959
2960 health->populate();
2961
2962 getMainChassisId(
2963 asyncResp, [](const std::string& chassisId,
2964 const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
2965 aRsp->res.jsonValue["Links"]["Chassis"] = {
2966 {{"@odata.id", "/redfish/v1/Chassis/" + chassisId}}};
2967 });
2968
2969 getLocationIndicatorActive(asyncResp);
2970 // TODO (Gunnar): Remove IndicatorLED after enough time has passed
2971 getIndicatorLedState(asyncResp);
2972 getComputerSystem(asyncResp, health);
2973 getHostState(asyncResp);
2974 getBootProperties(asyncResp);
2975 getBootProgress(asyncResp);
2976 getPCIeDeviceList(asyncResp, "PCIeDevices");
2977 getHostWatchdogTimer(asyncResp);
2978 getPowerRestorePolicy(asyncResp);
2979 getAutomaticRetry(asyncResp);
2980 getLastResetTime(asyncResp);
2981#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
2982 getProvisioningStatus(asyncResp);
2983#endif
Ali Ahmed19817712021-06-29 17:01:52 -05002984 getTrustedModuleRequiredToBoot(asyncResp);
Chris Cain3a2d04242021-05-28 16:57:10 -05002985 getPowerMode(asyncResp);
Chris Cain37bbf982021-09-20 10:53:09 -05002986 getIdlePowerSaver(asyncResp);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002987 });
2988 BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/")
Ed Tanoused398212021-06-09 17:05:54 -07002989 .privileges(redfish::privileges::patchComputerSystem)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002990 .methods(boost::beast::http::verb::patch)(
2991 [](const crow::Request& req,
2992 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
2993 std::optional<bool> locationIndicatorActive;
2994 std::optional<std::string> indicatorLed;
2995 std::optional<nlohmann::json> bootProps;
2996 std::optional<nlohmann::json> wdtTimerProps;
2997 std::optional<std::string> assetTag;
2998 std::optional<std::string> powerRestorePolicy;
Chris Cain3a2d04242021-05-28 16:57:10 -05002999 std::optional<std::string> powerMode;
Chris Cain37bbf982021-09-20 10:53:09 -05003000 std::optional<nlohmann::json> ipsProps;
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003001 if (!json_util::readJson(
3002 req, asyncResp->res, "IndicatorLED", indicatorLed,
3003 "LocationIndicatorActive", locationIndicatorActive,
3004 "Boot", bootProps, "WatchdogTimer", wdtTimerProps,
3005 "PowerRestorePolicy", powerRestorePolicy, "AssetTag",
Chris Cain37bbf982021-09-20 10:53:09 -05003006 assetTag, "PowerMode", powerMode, "IdlePowerSaver",
3007 ipsProps))
James Feistb49ac872019-05-21 15:12:01 -07003008 {
James Feistb49ac872019-05-21 15:12:01 -07003009 return;
3010 }
3011
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003012 asyncResp->res.result(boost::beast::http::status::no_content);
James Feistb49ac872019-05-21 15:12:01 -07003013
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003014 if (assetTag)
3015 {
3016 setAssetTag(asyncResp, *assetTag);
3017 }
James Feistb49ac872019-05-21 15:12:01 -07003018
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003019 if (wdtTimerProps)
3020 {
3021 std::optional<bool> wdtEnable;
3022 std::optional<std::string> wdtTimeOutAction;
3023
3024 if (!json_util::readJson(*wdtTimerProps, asyncResp->res,
3025 "FunctionEnabled", wdtEnable,
3026 "TimeoutAction", wdtTimeOutAction))
3027 {
3028 return;
3029 }
3030 setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
3031 }
3032
3033 if (bootProps)
3034 {
3035 std::optional<std::string> bootSource;
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03003036 std::optional<std::string> bootType;
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003037 std::optional<std::string> bootEnable;
3038 std::optional<std::string> automaticRetryConfig;
Ali Ahmedac7e1e02021-09-15 21:02:57 -05003039 std::optional<bool> trustedModuleRequiredToBoot;
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003040
3041 if (!json_util::readJson(
3042 *bootProps, asyncResp->res,
3043 "BootSourceOverrideTarget", bootSource,
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03003044 "BootSourceOverrideMode", bootType,
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003045 "BootSourceOverrideEnabled", bootEnable,
Ali Ahmedac7e1e02021-09-15 21:02:57 -05003046 "AutomaticRetryConfig", automaticRetryConfig,
3047 "TrustedModuleRequiredToBoot",
3048 trustedModuleRequiredToBoot))
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003049 {
3050 return;
3051 }
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03003052
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03003053 if (bootSource || bootType || bootEnable)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003054 {
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03003055 setBootProperties(asyncResp, bootSource, bootType,
3056 bootEnable);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003057 }
3058 if (automaticRetryConfig)
3059 {
3060 setAutomaticRetry(asyncResp, *automaticRetryConfig);
3061 }
Ali Ahmedac7e1e02021-09-15 21:02:57 -05003062
3063 if (trustedModuleRequiredToBoot)
3064 {
3065 setTrustedModuleRequiredToBoot(
3066 asyncResp, *trustedModuleRequiredToBoot);
3067 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003068 }
3069
3070 if (locationIndicatorActive)
3071 {
3072 setLocationIndicatorActive(asyncResp,
3073 *locationIndicatorActive);
3074 }
3075
3076 // TODO (Gunnar): Remove IndicatorLED after enough time has
3077 // passed
3078 if (indicatorLed)
3079 {
3080 setIndicatorLedState(asyncResp, *indicatorLed);
3081 asyncResp->res.addHeader(
3082 boost::beast::http::field::warning,
3083 "299 - \"IndicatorLED is deprecated. Use "
3084 "LocationIndicatorActive instead.\"");
3085 }
3086
3087 if (powerRestorePolicy)
3088 {
3089 setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
3090 }
Chris Cain3a2d04242021-05-28 16:57:10 -05003091
3092 if (powerMode)
3093 {
3094 setPowerMode(asyncResp, *powerMode);
3095 }
Chris Cain37bbf982021-09-20 10:53:09 -05003096
3097 if (ipsProps)
3098 {
3099 std::optional<bool> ipsEnable;
3100 std::optional<uint8_t> ipsEnterUtil;
3101 std::optional<uint64_t> ipsEnterTime;
3102 std::optional<uint8_t> ipsExitUtil;
3103 std::optional<uint64_t> ipsExitTime;
3104
3105 if (!json_util::readJson(
3106 *ipsProps, asyncResp->res, "Enabled", ipsEnable,
3107 "EnterUtilizationPercent", ipsEnterUtil,
3108 "EnterDwellTimeSeconds", ipsEnterTime,
3109 "ExitUtilizationPercent", ipsExitUtil,
3110 "ExitDwellTimeSeconds", ipsExitTime))
3111 {
3112 return;
3113 }
3114 setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil,
3115 ipsEnterTime, ipsExitUtil, ipsExitTime);
3116 }
zhanghch058d1b46d2021-04-01 11:18:24 +08003117 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003118}
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303119
3120/**
3121 * SystemResetActionInfo derived class for delivering Computer Systems
3122 * ResetType AllowableValues using ResetInfo schema.
3123 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003124inline void requestRoutesSystemResetActionInfo(App& app)
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303125{
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303126
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303127 /**
3128 * Functions triggers appropriate requests on DBus
3129 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003130 BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/ResetActionInfo/")
Ed Tanoused398212021-06-09 17:05:54 -07003131 .privileges(redfish::privileges::getActionInfo)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003132 .methods(boost::beast::http::verb::get)(
3133 [](const crow::Request&,
3134 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
3135 asyncResp->res.jsonValue = {
3136 {"@odata.type", "#ActionInfo.v1_1_2.ActionInfo"},
3137 {"@odata.id", "/redfish/v1/Systems/system/ResetActionInfo"},
3138 {"Name", "Reset Action Info"},
3139 {"Id", "ResetActionInfo"},
3140 {"Parameters",
3141 {{{"Name", "ResetType"},
3142 {"Required", true},
3143 {"DataType", "String"},
3144 {"AllowableValues",
3145 {"On", "ForceOff", "ForceOn", "ForceRestart",
3146 "GracefulRestart", "GracefulShutdown", "PowerCycle",
3147 "Nmi"}}}}}};
3148 });
3149}
Ed Tanous1abe55e2018-09-05 08:30:59 -07003150} // namespace redfish