blob: 26905bf7014e86f963a42851a523b5a1fb571aae [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
Willy Tu13451e32023-05-24 16:08:18 -070018#include "bmcweb_config.h"
19
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080020#include "app.hpp"
Jonathan Doman1e1e5982021-06-11 09:36:17 -070021#include "dbus_singleton.hpp"
George Liu7a1dbc42022-12-07 16:03:22 +080022#include "dbus_utility.hpp"
James Feistb49ac872019-05-21 15:12:01 -070023#include "health.hpp"
Asmitha Karunanithi746b56f2023-02-27 23:29:49 -060024#include "hypervisor_system.hpp"
James Feist1c8fba92019-12-20 15:12:07 -080025#include "led.hpp"
Ed Tanousf4c99e72021-10-04 17:02:43 -070026#include "query.hpp"
Jennifer Leec5d03ff2019-03-08 15:42:58 -080027#include "redfish_util.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080028#include "registries/privilege_registry.hpp"
29#include "utils/dbus_utils.hpp"
30#include "utils/json_utils.hpp"
Lakshmi Yadlapati472bd202023-03-22 09:57:05 -050031#include "utils/pcie_util.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080032#include "utils/sw_utils.hpp"
Ed Tanous2b829372022-08-03 14:22:34 -070033#include "utils/time_utils.hpp"
Jennifer Leec5d03ff2019-03-08 15:42:58 -080034
Andrew Geisslerfc903b32023-05-31 14:15:42 -040035#include <boost/asio/error.hpp>
Ed Tanous9712f8a2018-09-21 13:38:49 -070036#include <boost/container/flat_map.hpp>
George Liue99073f2022-12-09 11:06:16 +080037#include <boost/system/error_code.hpp>
Ed Tanousef4c65b2023-04-24 15:28:50 -070038#include <boost/url/format.hpp>
Jonathan Doman1e1e5982021-06-11 09:36:17 -070039#include <sdbusplus/asio/property.hpp>
Andrew Geisslerfc903b32023-05-31 14:15:42 -040040#include <sdbusplus/message.hpp>
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +020041#include <sdbusplus/unpack_properties.hpp>
Gunnar Mills1214b7e2020-06-04 10:11:30 -050042
George Liu7a1dbc42022-12-07 16:03:22 +080043#include <array>
44#include <string_view>
Ed Tanousabf2add2019-01-22 16:40:12 -080045#include <variant>
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020046
Ed Tanous1abe55e2018-09-05 08:30:59 -070047namespace redfish
48{
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020049
Abhishek Patel5c3e9272021-06-24 10:11:33 -050050const static std::array<std::pair<std::string_view, std::string_view>, 2>
51 protocolToDBusForSystems{
52 {{"SSH", "obmc-console-ssh"}, {"IPMI", "phosphor-ipmi-net"}}};
53
Alpana Kumari9d3ae102019-04-12 06:49:32 -050054/**
55 * @brief Updates the Functional State of DIMMs
56 *
Ed Tanousac106bf2023-06-07 09:24:59 -070057 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Alpana Kumari9d3ae102019-04-12 06:49:32 -050058 * @param[in] dimmState Dimm's Functional state, true/false
59 *
60 * @return None.
61 */
zhanghch058d1b46d2021-04-01 11:18:24 +080062inline void
Ed Tanousac106bf2023-06-07 09:24:59 -070063 updateDimmProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Jonathan Doman1e1e5982021-06-11 09:36:17 -070064 bool isDimmFunctional)
Alpana Kumari9d3ae102019-04-12 06:49:32 -050065{
Jonathan Doman1e1e5982021-06-11 09:36:17 -070066 BMCWEB_LOG_DEBUG << "Dimm Functional: " << isDimmFunctional;
Alpana Kumari9d3ae102019-04-12 06:49:32 -050067
Gunnar Mills4e0453b2020-07-08 14:00:30 -050068 // Set it as Enabled if at least one DIMM is functional
Alpana Kumari9d3ae102019-04-12 06:49:32 -050069 // Update STATE only if previous State was DISABLED and current Dimm is
70 // ENABLED.
Ed Tanous02cad962022-06-30 16:50:15 -070071 const nlohmann::json& prevMemSummary =
Ed Tanousac106bf2023-06-07 09:24:59 -070072 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"];
Alpana Kumari9d3ae102019-04-12 06:49:32 -050073 if (prevMemSummary == "Disabled")
74 {
Ed Tanouse05aec52022-01-25 10:28:56 -080075 if (isDimmFunctional)
Alpana Kumari9d3ae102019-04-12 06:49:32 -050076 {
Ed Tanousac106bf2023-06-07 09:24:59 -070077 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
Alpana Kumari9d3ae102019-04-12 06:49:32 -050078 "Enabled";
79 }
80 }
81}
82
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050083/*
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050084 * @brief Update "ProcessorSummary" "Status" "State" based on
85 * CPU Functional State
86 *
Ed Tanousac106bf2023-06-07 09:24:59 -070087 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050088 * @param[in] cpuFunctionalState is CPU functional true/false
89 *
90 * @return None.
91 */
Ed Tanousac106bf2023-06-07 09:24:59 -070092inline void modifyCpuFunctionalState(
93 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isCpuFunctional)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050094{
Jonathan Doman1e1e5982021-06-11 09:36:17 -070095 BMCWEB_LOG_DEBUG << "Cpu Functional: " << isCpuFunctional;
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050096
Ed Tanous02cad962022-06-30 16:50:15 -070097 const nlohmann::json& prevProcState =
Ed Tanousac106bf2023-06-07 09:24:59 -070098 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"];
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050099
Gunnar Mills4e0453b2020-07-08 14:00:30 -0500100 // Set it as Enabled if at least one CPU is functional
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500101 // Update STATE only if previous State was Non_Functional and current CPU is
102 // Functional.
103 if (prevProcState == "Disabled")
104 {
Ed Tanouse05aec52022-01-25 10:28:56 -0800105 if (isCpuFunctional)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500106 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700107 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500108 "Enabled";
109 }
110 }
111}
112
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500113/*
114 * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState
115 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700116 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500117 * @param[in] cpuPresenceState CPU present or not
118 *
119 * @return None.
120 */
121inline void
Ed Tanousac106bf2023-06-07 09:24:59 -0700122 modifyCpuPresenceState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500123 bool isCpuPresent)
124{
125 BMCWEB_LOG_DEBUG << "Cpu Present: " << isCpuPresent;
126
127 if (isCpuPresent)
128 {
129 nlohmann::json& procCount =
Ed Tanousac106bf2023-06-07 09:24:59 -0700130 asyncResp->res.jsonValue["ProcessorSummary"]["Count"];
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500131 auto* procCountPtr =
132 procCount.get_ptr<nlohmann::json::number_integer_t*>();
133 if (procCountPtr != nullptr)
134 {
135 // shouldn't be possible to be nullptr
136 *procCountPtr += 1;
137 }
138 }
139}
140
Ali Ahmed382d6472021-09-03 16:53:53 -0500141inline void getProcessorProperties(
Ed Tanousac106bf2023-06-07 09:24:59 -0700142 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ali Ahmed382d6472021-09-03 16:53:53 -0500143 const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>&
144 properties)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500145{
Ali Ahmed03fbed92021-09-03 02:33:43 -0500146 BMCWEB_LOG_DEBUG << "Got " << properties.size() << " Cpu properties.";
147
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200148 // TODO: Get Model
149
150 const uint16_t* coreCount = nullptr;
151
152 const bool success = sdbusplus::unpackPropertiesNoThrow(
153 dbus_utils::UnpackErrorPrinter(), properties, "CoreCount", coreCount);
154
155 if (!success)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500156 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700157 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200158 return;
159 }
Ali Ahmed03fbed92021-09-03 02:33:43 -0500160
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200161 if (coreCount != nullptr)
162 {
163 nlohmann::json& coreCountJson =
Ed Tanousac106bf2023-06-07 09:24:59 -0700164 asyncResp->res.jsonValue["ProcessorSummary"]["CoreCount"];
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200165 uint64_t* coreCountJsonPtr = coreCountJson.get_ptr<uint64_t*>();
Ali Ahmed03fbed92021-09-03 02:33:43 -0500166
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200167 if (coreCountJsonPtr == nullptr)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500168 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200169 coreCountJson = *coreCount;
170 }
171 else
172 {
173 *coreCountJsonPtr += *coreCount;
Ali Ahmed03fbed92021-09-03 02:33:43 -0500174 }
175 }
176}
177
178/*
179 * @brief Get ProcessorSummary fields
180 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700181 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Ali Ahmed03fbed92021-09-03 02:33:43 -0500182 * @param[in] service dbus service for Cpu Information
183 * @param[in] path dbus path for Cpu
184 *
185 * @return None.
186 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700187inline void
188 getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
189 const std::string& service, const std::string& path)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500190{
Ed Tanousac106bf2023-06-07 09:24:59 -0700191 auto getCpuPresenceState = [asyncResp](const boost::system::error_code& ec3,
192 const bool cpuPresenceCheck) {
Ali Ahmed382d6472021-09-03 16:53:53 -0500193 if (ec3)
194 {
195 BMCWEB_LOG_ERROR << "DBUS response error " << ec3;
196 return;
197 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700198 modifyCpuPresenceState(asyncResp, cpuPresenceCheck);
Ali Ahmed382d6472021-09-03 16:53:53 -0500199 };
200
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500201 // Get the Presence of CPU
202 sdbusplus::asio::getProperty<bool>(
203 *crow::connections::systemBus, service, path,
204 "xyz.openbmc_project.Inventory.Item", "Present",
205 std::move(getCpuPresenceState));
206
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500207 if constexpr (bmcwebEnableProcMemStatus)
208 {
209 auto getCpuFunctionalState =
Ed Tanousac106bf2023-06-07 09:24:59 -0700210 [asyncResp](const boost::system::error_code& ec3,
211 const bool cpuFunctionalCheck) {
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500212 if (ec3)
213 {
214 BMCWEB_LOG_ERROR << "DBUS response error " << ec3;
215 return;
216 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700217 modifyCpuFunctionalState(asyncResp, cpuFunctionalCheck);
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500218 };
Ali Ahmed382d6472021-09-03 16:53:53 -0500219
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500220 // Get the Functional State
221 sdbusplus::asio::getProperty<bool>(
222 *crow::connections::systemBus, service, path,
223 "xyz.openbmc_project.State.Decorator.OperationalStatus",
224 "Functional", std::move(getCpuFunctionalState));
225 }
Ali Ahmed382d6472021-09-03 16:53:53 -0500226
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200227 sdbusplus::asio::getAllProperties(
228 *crow::connections::systemBus, service, path,
229 "xyz.openbmc_project.Inventory.Item.Cpu",
Ed Tanousac106bf2023-06-07 09:24:59 -0700230 [asyncResp, service,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800231 path](const boost::system::error_code& ec2,
Ed Tanousb9d36b42022-02-26 21:42:46 -0800232 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700233 if (ec2)
234 {
235 BMCWEB_LOG_ERROR << "DBUS response error " << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -0700236 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -0700237 return;
238 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700239 getProcessorProperties(asyncResp, properties);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200240 });
Ali Ahmed03fbed92021-09-03 02:33:43 -0500241}
242
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500243/*
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500244 * @brief processMemoryProperties fields
245 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700246 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500247 * @param[in] service dbus service for memory Information
248 * @param[in] path dbus path for Memory
249 * @param[in] DBUS properties for memory
250 *
251 * @return None.
252 */
253inline void
Ed Tanousac106bf2023-06-07 09:24:59 -0700254 processMemoryProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500255 [[maybe_unused]] const std::string& service,
256 [[maybe_unused]] const std::string& path,
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500257 const dbus::utility::DBusPropertiesMap& properties)
258{
259 BMCWEB_LOG_DEBUG << "Got " << properties.size() << " Dimm properties.";
260
261 if (properties.empty())
262 {
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500263 if constexpr (bmcwebEnableProcMemStatus)
264 {
265 sdbusplus::asio::getProperty<bool>(
266 *crow::connections::systemBus, service, path,
267 "xyz.openbmc_project.State."
268 "Decorator.OperationalStatus",
269 "Functional",
Ed Tanousac106bf2023-06-07 09:24:59 -0700270 [asyncResp](const boost::system::error_code& ec3,
271 bool dimmState) {
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500272 if (ec3)
273 {
274 BMCWEB_LOG_ERROR << "DBUS response error " << ec3;
275 return;
276 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700277 updateDimmProperties(asyncResp, dimmState);
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500278 });
279 }
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500280 return;
281 }
282
283 const size_t* memorySizeInKB = nullptr;
284
285 const bool success = sdbusplus::unpackPropertiesNoThrow(
286 dbus_utils::UnpackErrorPrinter(), properties, "MemorySizeInKB",
287 memorySizeInKB);
288
289 if (!success)
290 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700291 messages::internalError(asyncResp->res);
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500292 return;
293 }
294
295 if (memorySizeInKB != nullptr)
296 {
297 nlohmann::json& totalMemory =
Ed Tanousac106bf2023-06-07 09:24:59 -0700298 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"];
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500299 const uint64_t* preValue = totalMemory.get_ptr<const uint64_t*>();
300 if (preValue == nullptr)
301 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700302 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500303 *memorySizeInKB / static_cast<size_t>(1024 * 1024);
304 }
305 else
306 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700307 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500308 *memorySizeInKB / static_cast<size_t>(1024 * 1024) + *preValue;
309 }
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500310 if constexpr (bmcwebEnableProcMemStatus)
311 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700312 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500313 "Enabled";
314 }
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500315 }
316}
317
318/*
319 * @brief Get getMemorySummary fields
320 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700321 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500322 * @param[in] service dbus service for memory Information
323 * @param[in] path dbus path for memory
324 *
325 * @return None.
326 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700327inline void
328 getMemorySummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
329 const std::string& service, const std::string& path)
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500330{
331 sdbusplus::asio::getAllProperties(
332 *crow::connections::systemBus, service, path,
333 "xyz.openbmc_project.Inventory.Item.Dimm",
Ed Tanousac106bf2023-06-07 09:24:59 -0700334 [asyncResp, service,
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500335 path](const boost::system::error_code& ec2,
336 const dbus::utility::DBusPropertiesMap& properties) {
337 if (ec2)
338 {
339 BMCWEB_LOG_ERROR << "DBUS response error " << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -0700340 messages::internalError(asyncResp->res);
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500341 return;
342 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700343 processMemoryProperties(asyncResp, service, path, properties);
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500344 });
345}
346
347/*
Ed Tanous6c34de42018-08-29 13:37:36 -0700348 * @brief Retrieves computer system properties over dbus
349 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700350 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Gunnar Mills8f9ee3c2020-10-30 16:15:13 -0500351 * @param[in] systemHealth Shared HealthPopulate pointer
Ed Tanous6c34de42018-08-29 13:37:36 -0700352 *
353 * @return None.
354 */
Ed Tanousb5a76932020-09-29 16:16:58 -0700355inline void
Ed Tanousac106bf2023-06-07 09:24:59 -0700356 getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanousb5a76932020-09-29 16:16:58 -0700357 const std::shared_ptr<HealthPopulate>& systemHealth)
Ed Tanous6c34de42018-08-29 13:37:36 -0700358{
Ed Tanous6c34de42018-08-29 13:37:36 -0700359 BMCWEB_LOG_DEBUG << "Get available system components.";
George Liue99073f2022-12-09 11:06:16 +0800360 constexpr std::array<std::string_view, 5> interfaces = {
361 "xyz.openbmc_project.Inventory.Decorator.Asset",
362 "xyz.openbmc_project.Inventory.Item.Cpu",
363 "xyz.openbmc_project.Inventory.Item.Dimm",
364 "xyz.openbmc_project.Inventory.Item.System",
365 "xyz.openbmc_project.Common.UUID",
366 };
367 dbus::utility::getSubTree(
368 "/xyz/openbmc_project/inventory", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -0700369 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +0800370 systemHealth](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -0800371 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700372 if (ec)
373 {
374 BMCWEB_LOG_DEBUG << "DBUS response error";
Ed Tanousac106bf2023-06-07 09:24:59 -0700375 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -0700376 return;
377 }
378 // Iterate over all retrieved ObjectPaths.
379 for (const std::pair<
380 std::string,
381 std::vector<std::pair<std::string, std::vector<std::string>>>>&
382 object : subtree)
383 {
384 const std::string& path = object.first;
385 BMCWEB_LOG_DEBUG << "Got path: " << path;
386 const std::vector<std::pair<std::string, std::vector<std::string>>>&
387 connectionNames = object.second;
388 if (connectionNames.empty())
Ed Tanous6c34de42018-08-29 13:37:36 -0700389 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700390 continue;
Ed Tanous6c34de42018-08-29 13:37:36 -0700391 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700392
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500393 std::shared_ptr<HealthPopulate> memoryHealth = nullptr;
394 std::shared_ptr<HealthPopulate> cpuHealth = nullptr;
Ed Tanous002d39b2022-05-31 08:59:27 -0700395
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500396 if constexpr (bmcwebEnableProcMemStatus)
Willy Tu13451e32023-05-24 16:08:18 -0700397 {
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500398 memoryHealth = std::make_shared<HealthPopulate>(
Ed Tanousac106bf2023-06-07 09:24:59 -0700399 asyncResp, "/MemorySummary/Status"_json_pointer);
Willy Tu13451e32023-05-24 16:08:18 -0700400 systemHealth->children.emplace_back(memoryHealth);
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500401
402 if constexpr (bmcwebEnableHealthPopulate)
403 {
404 cpuHealth = std::make_shared<HealthPopulate>(
Ed Tanousac106bf2023-06-07 09:24:59 -0700405 asyncResp, "/ProcessorSummary/Status"_json_pointer);
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500406
407 systemHealth->children.emplace_back(cpuHealth);
408 }
Willy Tu13451e32023-05-24 16:08:18 -0700409 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700410
411 // This is not system, so check if it's cpu, dimm, UUID or
412 // BiosVer
413 for (const auto& connection : connectionNames)
Ed Tanous6c34de42018-08-29 13:37:36 -0700414 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700415 for (const auto& interfaceName : connection.second)
Ed Tanous6c34de42018-08-29 13:37:36 -0700416 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700417 if (interfaceName ==
418 "xyz.openbmc_project.Inventory.Item.Dimm")
Ed Tanous6c34de42018-08-29 13:37:36 -0700419 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700420 BMCWEB_LOG_DEBUG
421 << "Found Dimm, now get its properties.";
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500422
Ed Tanousac106bf2023-06-07 09:24:59 -0700423 getMemorySummary(asyncResp, connection.first, path);
Ed Tanous002d39b2022-05-31 08:59:27 -0700424
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500425 if constexpr (bmcwebEnableProcMemStatus)
426 {
427 memoryHealth->inventory.emplace_back(path);
428 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700429 }
430 else if (interfaceName ==
431 "xyz.openbmc_project.Inventory.Item.Cpu")
432 {
433 BMCWEB_LOG_DEBUG
434 << "Found Cpu, now get its properties.";
435
Ed Tanousac106bf2023-06-07 09:24:59 -0700436 getProcessorSummary(asyncResp, connection.first, path);
Ed Tanous002d39b2022-05-31 08:59:27 -0700437
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500438 if constexpr (bmcwebEnableProcMemStatus)
439 {
440 cpuHealth->inventory.emplace_back(path);
441 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700442 }
443 else if (interfaceName == "xyz.openbmc_project.Common.UUID")
444 {
445 BMCWEB_LOG_DEBUG
446 << "Found UUID, now get its properties.";
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200447
448 sdbusplus::asio::getAllProperties(
449 *crow::connections::systemBus, connection.first,
450 path, "xyz.openbmc_project.Common.UUID",
Ed Tanousac106bf2023-06-07 09:24:59 -0700451 [asyncResp](const boost::system::error_code& ec3,
452 const dbus::utility::DBusPropertiesMap&
453 properties) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700454 if (ec3)
455 {
456 BMCWEB_LOG_DEBUG << "DBUS response error "
457 << ec3;
Ed Tanousac106bf2023-06-07 09:24:59 -0700458 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -0700459 return;
460 }
461 BMCWEB_LOG_DEBUG << "Got " << properties.size()
462 << " UUID properties.";
Ed Tanous002d39b2022-05-31 08:59:27 -0700463
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200464 const std::string* uUID = nullptr;
465
466 const bool success =
467 sdbusplus::unpackPropertiesNoThrow(
468 dbus_utils::UnpackErrorPrinter(),
469 properties, "UUID", uUID);
470
471 if (!success)
472 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700473 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200474 return;
Ed Tanous002d39b2022-05-31 08:59:27 -0700475 }
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200476
477 if (uUID != nullptr)
478 {
479 std::string valueStr = *uUID;
480 if (valueStr.size() == 32)
481 {
482 valueStr.insert(8, 1, '-');
483 valueStr.insert(13, 1, '-');
484 valueStr.insert(18, 1, '-');
485 valueStr.insert(23, 1, '-');
486 }
487 BMCWEB_LOG_DEBUG << "UUID = " << valueStr;
Ed Tanousac106bf2023-06-07 09:24:59 -0700488 asyncResp->res.jsonValue["UUID"] = valueStr;
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200489 }
490 });
Ed Tanous002d39b2022-05-31 08:59:27 -0700491 }
492 else if (interfaceName ==
493 "xyz.openbmc_project.Inventory.Item.System")
494 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200495 sdbusplus::asio::getAllProperties(
496 *crow::connections::systemBus, connection.first,
497 path,
498 "xyz.openbmc_project.Inventory.Decorator.Asset",
Ed Tanousac106bf2023-06-07 09:24:59 -0700499 [asyncResp](const boost::system::error_code& ec2,
500 const dbus::utility::DBusPropertiesMap&
501 propertiesList) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700502 if (ec2)
503 {
504 // doesn't have to include this
505 // interface
506 return;
507 }
508 BMCWEB_LOG_DEBUG << "Got " << propertiesList.size()
509 << " properties for system";
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200510
511 const std::string* partNumber = nullptr;
512 const std::string* serialNumber = nullptr;
513 const std::string* manufacturer = nullptr;
514 const std::string* model = nullptr;
515 const std::string* subModel = nullptr;
516
517 const bool success =
518 sdbusplus::unpackPropertiesNoThrow(
519 dbus_utils::UnpackErrorPrinter(),
520 propertiesList, "PartNumber", partNumber,
521 "SerialNumber", serialNumber,
522 "Manufacturer", manufacturer, "Model",
523 model, "SubModel", subModel);
524
525 if (!success)
Ed Tanous002d39b2022-05-31 08:59:27 -0700526 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700527 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200528 return;
529 }
530
531 if (partNumber != nullptr)
532 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700533 asyncResp->res.jsonValue["PartNumber"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200534 *partNumber;
535 }
536
537 if (serialNumber != nullptr)
538 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700539 asyncResp->res.jsonValue["SerialNumber"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200540 *serialNumber;
541 }
542
543 if (manufacturer != nullptr)
544 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700545 asyncResp->res.jsonValue["Manufacturer"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200546 *manufacturer;
547 }
548
549 if (model != nullptr)
550 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700551 asyncResp->res.jsonValue["Model"] = *model;
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200552 }
553
554 if (subModel != nullptr)
555 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700556 asyncResp->res.jsonValue["SubModel"] =
557 *subModel;
Ed Tanous002d39b2022-05-31 08:59:27 -0700558 }
Gunnar Millsc1e236a2020-04-14 21:36:33 -0500559
Ed Tanous002d39b2022-05-31 08:59:27 -0700560 // Grab the bios version
Willy Tueee00132022-06-14 14:53:17 -0700561 sw_util::populateSoftwareInformation(
Ed Tanousac106bf2023-06-07 09:24:59 -0700562 asyncResp, sw_util::biosPurpose, "BiosVersion",
Ed Tanous002d39b2022-05-31 08:59:27 -0700563 false);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200564 });
James Feiste4a4b9a2019-06-20 14:08:07 -0700565
Ed Tanous002d39b2022-05-31 08:59:27 -0700566 sdbusplus::asio::getProperty<std::string>(
567 *crow::connections::systemBus, connection.first,
568 path,
569 "xyz.openbmc_project.Inventory.Decorator."
570 "AssetTag",
571 "AssetTag",
Ed Tanousac106bf2023-06-07 09:24:59 -0700572 [asyncResp](const boost::system::error_code& ec2,
573 const std::string& value) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700574 if (ec2)
575 {
576 // doesn't have to include this
577 // interface
578 return;
579 }
James Feiste4a4b9a2019-06-20 14:08:07 -0700580
Ed Tanousac106bf2023-06-07 09:24:59 -0700581 asyncResp->res.jsonValue["AssetTag"] = value;
Ed Tanous002d39b2022-05-31 08:59:27 -0700582 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700583 }
584 }
585 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700586 }
Ed Tanous66173382018-08-15 18:20:59 -0700587 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700588}
589
590/**
Ed Tanous6c34de42018-08-29 13:37:36 -0700591 * @brief Retrieves host state properties over dbus
592 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700593 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Ed Tanous6c34de42018-08-29 13:37:36 -0700594 *
595 * @return None.
596 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700597inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Ed Tanous6c34de42018-08-29 13:37:36 -0700598{
599 BMCWEB_LOG_DEBUG << "Get host information.";
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700600 sdbusplus::asio::getProperty<std::string>(
601 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
602 "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host",
603 "CurrentHostState",
Ed Tanousac106bf2023-06-07 09:24:59 -0700604 [asyncResp](const boost::system::error_code& ec,
605 const std::string& hostState) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700606 if (ec)
607 {
608 if (ec == boost::system::errc::host_unreachable)
Ed Tanous6c34de42018-08-29 13:37:36 -0700609 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700610 // Service not available, no error, just don't return
611 // host state info
612 BMCWEB_LOG_DEBUG << "Service not available " << ec;
Ed Tanous6c34de42018-08-29 13:37:36 -0700613 return;
614 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700615 BMCWEB_LOG_ERROR << "DBUS response error " << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -0700616 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -0700617 return;
618 }
Ed Tanous66173382018-08-15 18:20:59 -0700619
Ed Tanous002d39b2022-05-31 08:59:27 -0700620 BMCWEB_LOG_DEBUG << "Host state: " << hostState;
621 // Verify Host State
622 if (hostState == "xyz.openbmc_project.State.Host.HostState.Running")
623 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700624 asyncResp->res.jsonValue["PowerState"] = "On";
625 asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
Ed Tanous002d39b2022-05-31 08:59:27 -0700626 }
627 else if (hostState ==
628 "xyz.openbmc_project.State.Host.HostState.Quiesced")
629 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700630 asyncResp->res.jsonValue["PowerState"] = "On";
631 asyncResp->res.jsonValue["Status"]["State"] = "Quiesced";
Ed Tanous002d39b2022-05-31 08:59:27 -0700632 }
633 else if (hostState ==
634 "xyz.openbmc_project.State.Host.HostState.DiagnosticMode")
635 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700636 asyncResp->res.jsonValue["PowerState"] = "On";
637 asyncResp->res.jsonValue["Status"]["State"] = "InTest";
Ed Tanous002d39b2022-05-31 08:59:27 -0700638 }
639 else if (
640 hostState ==
641 "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning")
642 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700643 asyncResp->res.jsonValue["PowerState"] = "PoweringOn";
644 asyncResp->res.jsonValue["Status"]["State"] = "Starting";
Ed Tanous002d39b2022-05-31 08:59:27 -0700645 }
646 else if (hostState ==
647 "xyz.openbmc_project.State.Host.HostState.TransitioningToOff")
648 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700649 asyncResp->res.jsonValue["PowerState"] = "PoweringOff";
650 asyncResp->res.jsonValue["Status"]["State"] = "Disabled";
Ed Tanous002d39b2022-05-31 08:59:27 -0700651 }
652 else
653 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700654 asyncResp->res.jsonValue["PowerState"] = "Off";
655 asyncResp->res.jsonValue["Status"]["State"] = "Disabled";
Ed Tanous002d39b2022-05-31 08:59:27 -0700656 }
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700657 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700658}
659
660/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500661 * @brief Translates boot source DBUS property value to redfish.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530662 *
663 * @param[in] dbusSource The boot source in DBUS speak.
664 *
665 * @return Returns as a string, the boot source in Redfish terms. If translation
666 * cannot be done, returns an empty string.
667 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000668inline std::string dbusToRfBootSource(const std::string& dbusSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530669{
670 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
671 {
672 return "None";
673 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700674 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530675 {
676 return "Hdd";
677 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700678 if (dbusSource ==
679 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530680 {
681 return "Cd";
682 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700683 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530684 {
685 return "Pxe";
686 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700687 if (dbusSource ==
688 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700689 {
690 return "Usb";
691 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700692 return "";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530693}
694
695/**
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300696 * @brief Translates boot type DBUS property value to redfish.
697 *
698 * @param[in] dbusType The boot type in DBUS speak.
699 *
700 * @return Returns as a string, the boot type in Redfish terms. If translation
701 * cannot be done, returns an empty string.
702 */
703inline std::string dbusToRfBootType(const std::string& dbusType)
704{
705 if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy")
706 {
707 return "Legacy";
708 }
709 if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI")
710 {
711 return "UEFI";
712 }
713 return "";
714}
715
716/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500717 * @brief Translates boot mode DBUS property value to redfish.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530718 *
719 * @param[in] dbusMode The boot mode in DBUS speak.
720 *
721 * @return Returns as a string, the boot mode in Redfish terms. If translation
722 * cannot be done, returns an empty string.
723 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000724inline std::string dbusToRfBootMode(const std::string& dbusMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530725{
726 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
727 {
728 return "None";
729 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700730 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530731 {
732 return "Diags";
733 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700734 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530735 {
736 return "BiosSetup";
737 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700738 return "";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530739}
740
741/**
Andrew Geisslere43914b2022-01-06 13:59:39 -0600742 * @brief Translates boot progress DBUS property value to redfish.
743 *
744 * @param[in] dbusBootProgress The boot progress in DBUS speak.
745 *
746 * @return Returns as a string, the boot progress in Redfish terms. If
747 * translation cannot be done, returns "None".
748 */
749inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress)
750{
751 // Now convert the D-Bus BootProgress to the appropriate Redfish
752 // enum
753 std::string rfBpLastState = "None";
754 if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress."
755 "ProgressStages.Unspecified")
756 {
757 rfBpLastState = "None";
758 }
759 else if (dbusBootProgress ==
760 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
761 "PrimaryProcInit")
762 {
763 rfBpLastState = "PrimaryProcessorInitializationStarted";
764 }
765 else if (dbusBootProgress ==
766 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
767 "BusInit")
768 {
769 rfBpLastState = "BusInitializationStarted";
770 }
771 else if (dbusBootProgress ==
772 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
773 "MemoryInit")
774 {
775 rfBpLastState = "MemoryInitializationStarted";
776 }
777 else if (dbusBootProgress ==
778 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
779 "SecondaryProcInit")
780 {
781 rfBpLastState = "SecondaryProcessorInitializationStarted";
782 }
783 else if (dbusBootProgress ==
784 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
785 "PCIInit")
786 {
787 rfBpLastState = "PCIResourceConfigStarted";
788 }
789 else if (dbusBootProgress ==
790 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
791 "SystemSetup")
792 {
793 rfBpLastState = "SetupEntered";
794 }
795 else if (dbusBootProgress ==
796 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
797 "SystemInitComplete")
798 {
799 rfBpLastState = "SystemHardwareInitializationComplete";
800 }
801 else if (dbusBootProgress ==
802 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
803 "OSStart")
804 {
805 rfBpLastState = "OSBootStarted";
806 }
807 else if (dbusBootProgress ==
808 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
809 "OSRunning")
810 {
811 rfBpLastState = "OSRunning";
812 }
813 else
814 {
815 BMCWEB_LOG_DEBUG << "Unsupported D-Bus BootProgress "
816 << dbusBootProgress;
817 // Just return the default
818 }
819 return rfBpLastState;
820}
821
822/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500823 * @brief Translates boot source from Redfish to the DBus boot paths.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530824 *
825 * @param[in] rfSource The boot source in Redfish.
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700826 * @param[out] bootSource The DBus source
827 * @param[out] bootMode the DBus boot mode
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530828 *
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700829 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530830 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700831inline int
832 assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
833 const std::string& rfSource, std::string& bootSource,
834 std::string& bootMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530835{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300836 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
837 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700838
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530839 if (rfSource == "None")
840 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700841 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530842 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700843 if (rfSource == "Pxe")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530844 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700845 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
846 }
847 else if (rfSource == "Hdd")
848 {
849 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
850 }
851 else if (rfSource == "Diags")
852 {
853 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
854 }
855 else if (rfSource == "Cd")
856 {
857 bootSource =
858 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
859 }
860 else if (rfSource == "BiosSetup")
861 {
862 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530863 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700864 else if (rfSource == "Usb")
865 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700866 bootSource =
867 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700868 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530869 else
870 {
George Liu0fda0f12021-11-16 10:06:17 +0800871 BMCWEB_LOG_DEBUG
872 << "Invalid property value for BootSourceOverrideTarget: "
873 << bootSource;
Ed Tanousac106bf2023-06-07 09:24:59 -0700874 messages::propertyValueNotInList(asyncResp->res, rfSource,
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700875 "BootSourceTargetOverride");
876 return -1;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530877 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700878 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530879}
Ali Ahmed19817712021-06-29 17:01:52 -0500880
Andrew Geissler978b8802020-11-19 13:36:40 -0600881/**
882 * @brief Retrieves boot progress of the system
883 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700884 * @param[in] asyncResp Shared pointer for generating response message.
Andrew Geissler978b8802020-11-19 13:36:40 -0600885 *
886 * @return None.
887 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700888inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Andrew Geissler978b8802020-11-19 13:36:40 -0600889{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700890 sdbusplus::asio::getProperty<std::string>(
891 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
892 "/xyz/openbmc_project/state/host0",
893 "xyz.openbmc_project.State.Boot.Progress", "BootProgress",
Ed Tanousac106bf2023-06-07 09:24:59 -0700894 [asyncResp](const boost::system::error_code& ec,
895 const std::string& bootProgressStr) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700896 if (ec)
897 {
898 // BootProgress is an optional object so just do nothing if
899 // not found
900 return;
901 }
Andrew Geissler978b8802020-11-19 13:36:40 -0600902
Ed Tanous002d39b2022-05-31 08:59:27 -0700903 BMCWEB_LOG_DEBUG << "Boot Progress: " << bootProgressStr;
Andrew Geissler978b8802020-11-19 13:36:40 -0600904
Ed Tanousac106bf2023-06-07 09:24:59 -0700905 asyncResp->res.jsonValue["BootProgress"]["LastState"] =
Ed Tanous002d39b2022-05-31 08:59:27 -0700906 dbusToRfBootProgress(bootProgressStr);
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700907 });
Andrew Geissler978b8802020-11-19 13:36:40 -0600908}
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530909
910/**
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000911 * @brief Retrieves boot progress Last Update of the system
912 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700913 * @param[in] asyncResp Shared pointer for generating response message.
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000914 *
915 * @return None.
916 */
917inline void getBootProgressLastStateTime(
Ed Tanousac106bf2023-06-07 09:24:59 -0700918 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000919{
920 sdbusplus::asio::getProperty<uint64_t>(
921 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
922 "/xyz/openbmc_project/state/host0",
923 "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate",
Ed Tanousac106bf2023-06-07 09:24:59 -0700924 [asyncResp](const boost::system::error_code& ec,
925 const uint64_t lastStateTime) {
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000926 if (ec)
927 {
928 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
929 return;
930 }
931
932 // BootProgressLastUpdate is the last time the BootProgress property
933 // was updated. The time is the Epoch time, number of microseconds
934 // since 1 Jan 1970 00::00::00 UTC."
935 // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/
936 // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11
937
938 // Convert to ISO 8601 standard
Ed Tanousac106bf2023-06-07 09:24:59 -0700939 asyncResp->res.jsonValue["BootProgress"]["LastStateTime"] =
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000940 redfish::time_utils::getDateTimeUintUs(lastStateTime);
941 });
942}
943
944/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300945 * @brief Retrieves boot override type over DBUS and fills out the response
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300946 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700947 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300948 *
949 * @return None.
950 */
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300951
Ed Tanousac106bf2023-06-07 09:24:59 -0700952inline void
953 getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300954{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700955 sdbusplus::asio::getProperty<std::string>(
956 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
957 "/xyz/openbmc_project/control/host0/boot",
958 "xyz.openbmc_project.Control.Boot.Type", "BootType",
Ed Tanousac106bf2023-06-07 09:24:59 -0700959 [asyncResp](const boost::system::error_code& ec,
960 const std::string& bootType) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700961 if (ec)
962 {
963 // not an error, don't have to have the interface
964 return;
965 }
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300966
Ed Tanous002d39b2022-05-31 08:59:27 -0700967 BMCWEB_LOG_DEBUG << "Boot type: " << bootType;
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300968
Ed Tanousac106bf2023-06-07 09:24:59 -0700969 asyncResp->res
970 .jsonValue["Boot"]
971 ["BootSourceOverrideMode@Redfish.AllowableValues"] =
Ed Tanous613dabe2022-07-09 11:17:36 -0700972 nlohmann::json::array_t({"Legacy", "UEFI"});
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300973
Ed Tanous002d39b2022-05-31 08:59:27 -0700974 auto rfType = dbusToRfBootType(bootType);
975 if (rfType.empty())
976 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700977 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -0700978 return;
979 }
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300980
Ed Tanousac106bf2023-06-07 09:24:59 -0700981 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType;
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700982 });
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300983}
984
985/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300986 * @brief Retrieves boot override mode over DBUS and fills out the response
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530987 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700988 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530989 *
990 * @return None.
991 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300992
Ed Tanousac106bf2023-06-07 09:24:59 -0700993inline void
994 getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530995{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700996 sdbusplus::asio::getProperty<std::string>(
997 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
998 "/xyz/openbmc_project/control/host0/boot",
999 "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
Ed Tanousac106bf2023-06-07 09:24:59 -07001000 [asyncResp](const boost::system::error_code& ec,
1001 const std::string& bootModeStr) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001002 if (ec)
1003 {
1004 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07001005 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001006 return;
1007 }
1008
1009 BMCWEB_LOG_DEBUG << "Boot mode: " << bootModeStr;
1010
Ed Tanousac106bf2023-06-07 09:24:59 -07001011 asyncResp->res
Ed Tanous002d39b2022-05-31 08:59:27 -07001012 .jsonValue["Boot"]
1013 ["BootSourceOverrideTarget@Redfish.AllowableValues"] = {
1014 "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
1015
1016 if (bootModeStr !=
1017 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
1018 {
1019 auto rfMode = dbusToRfBootMode(bootModeStr);
1020 if (!rfMode.empty())
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301021 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001022 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001023 rfMode;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301024 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001025 }
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001026 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301027}
1028
1029/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001030 * @brief Retrieves boot override source over DBUS
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301031 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001032 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301033 *
1034 * @return None.
1035 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001036
1037inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001038 getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301039{
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001040 sdbusplus::asio::getProperty<std::string>(
1041 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1042 "/xyz/openbmc_project/control/host0/boot",
1043 "xyz.openbmc_project.Control.Boot.Source", "BootSource",
Ed Tanousac106bf2023-06-07 09:24:59 -07001044 [asyncResp](const boost::system::error_code& ec,
1045 const std::string& bootSourceStr) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001046 if (ec)
1047 {
1048 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Nan Zhou5ef735c2022-06-22 05:24:21 +00001049 if (ec.value() == boost::asio::error::host_unreachable)
1050 {
1051 return;
1052 }
Ed Tanousac106bf2023-06-07 09:24:59 -07001053 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001054 return;
1055 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301056
Ed Tanous002d39b2022-05-31 08:59:27 -07001057 BMCWEB_LOG_DEBUG << "Boot source: " << bootSourceStr;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301058
Ed Tanous002d39b2022-05-31 08:59:27 -07001059 auto rfSource = dbusToRfBootSource(bootSourceStr);
1060 if (!rfSource.empty())
1061 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001062 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
1063 rfSource;
Ed Tanous002d39b2022-05-31 08:59:27 -07001064 }
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001065
Ed Tanous002d39b2022-05-31 08:59:27 -07001066 // Get BootMode as BootSourceOverrideTarget is constructed
1067 // from both BootSource and BootMode
Ed Tanousac106bf2023-06-07 09:24:59 -07001068 getBootOverrideMode(asyncResp);
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001069 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301070}
1071
1072/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001073 * @brief This functions abstracts all the logic behind getting a
1074 * "BootSourceOverrideEnabled" property from an overall boot override enable
1075 * state
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301076 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001077 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301078 *
1079 * @return None.
1080 */
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301081
Ed Tanousac106bf2023-06-07 09:24:59 -07001082inline void processBootOverrideEnable(
1083 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1084 const bool bootOverrideEnableSetting)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001085{
1086 if (!bootOverrideEnableSetting)
1087 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001088 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1089 "Disabled";
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001090 return;
1091 }
1092
1093 // If boot source override is enabled, we need to check 'one_time'
1094 // property to set a correct value for the "BootSourceOverrideEnabled"
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001095 sdbusplus::asio::getProperty<bool>(
1096 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1097 "/xyz/openbmc_project/control/host0/boot/one_time",
1098 "xyz.openbmc_project.Object.Enable", "Enabled",
Ed Tanousac106bf2023-06-07 09:24:59 -07001099 [asyncResp](const boost::system::error_code& ec, bool oneTimeSetting) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001100 if (ec)
1101 {
1102 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07001103 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001104 return;
1105 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301106
Ed Tanous002d39b2022-05-31 08:59:27 -07001107 if (oneTimeSetting)
1108 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001109 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1110 "Once";
Ed Tanous002d39b2022-05-31 08:59:27 -07001111 }
1112 else
1113 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001114 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001115 "Continuous";
1116 }
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001117 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301118}
1119
1120/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001121 * @brief Retrieves boot override enable over DBUS
1122 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001123 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001124 *
1125 * @return None.
1126 */
1127
1128inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001129 getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001130{
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001131 sdbusplus::asio::getProperty<bool>(
1132 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1133 "/xyz/openbmc_project/control/host0/boot",
1134 "xyz.openbmc_project.Object.Enable", "Enabled",
Ed Tanousac106bf2023-06-07 09:24:59 -07001135 [asyncResp](const boost::system::error_code& ec,
1136 const bool bootOverrideEnable) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001137 if (ec)
1138 {
1139 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Nan Zhou5ef735c2022-06-22 05:24:21 +00001140 if (ec.value() == boost::asio::error::host_unreachable)
1141 {
1142 return;
1143 }
Ed Tanousac106bf2023-06-07 09:24:59 -07001144 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001145 return;
1146 }
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001147
Ed Tanousac106bf2023-06-07 09:24:59 -07001148 processBootOverrideEnable(asyncResp, bootOverrideEnable);
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001149 });
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001150}
1151
1152/**
1153 * @brief Retrieves boot source override properties
1154 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001155 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001156 *
1157 * @return None.
1158 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001159inline void
1160 getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001161{
1162 BMCWEB_LOG_DEBUG << "Get boot information.";
1163
Ed Tanousac106bf2023-06-07 09:24:59 -07001164 getBootOverrideSource(asyncResp);
1165 getBootOverrideType(asyncResp);
1166 getBootOverrideEnable(asyncResp);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001167}
1168
1169/**
Gunnar Millsc0557e12020-06-30 11:26:20 -05001170 * @brief Retrieves the Last Reset Time
1171 *
1172 * "Reset" is an overloaded term in Redfish, "Reset" includes power on
1173 * and power off. Even though this is the "system" Redfish object look at the
1174 * chassis D-Bus interface for the LastStateChangeTime since this has the
1175 * last power operation time.
1176 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001177 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Millsc0557e12020-06-30 11:26:20 -05001178 *
1179 * @return None.
1180 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001181inline void
1182 getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Gunnar Millsc0557e12020-06-30 11:26:20 -05001183{
1184 BMCWEB_LOG_DEBUG << "Getting System Last Reset Time";
1185
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001186 sdbusplus::asio::getProperty<uint64_t>(
1187 *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
1188 "/xyz/openbmc_project/state/chassis0",
1189 "xyz.openbmc_project.State.Chassis", "LastStateChangeTime",
Ed Tanousac106bf2023-06-07 09:24:59 -07001190 [asyncResp](const boost::system::error_code& ec,
1191 uint64_t lastResetTime) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001192 if (ec)
1193 {
1194 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
1195 return;
1196 }
Gunnar Millsc0557e12020-06-30 11:26:20 -05001197
Ed Tanous002d39b2022-05-31 08:59:27 -07001198 // LastStateChangeTime is epoch time, in milliseconds
1199 // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
1200 uint64_t lastResetTimeStamp = lastResetTime / 1000;
Gunnar Millsc0557e12020-06-30 11:26:20 -05001201
Ed Tanous002d39b2022-05-31 08:59:27 -07001202 // Convert to ISO 8601 standard
Ed Tanousac106bf2023-06-07 09:24:59 -07001203 asyncResp->res.jsonValue["LastResetTime"] =
Ed Tanous2b829372022-08-03 14:22:34 -07001204 redfish::time_utils::getDateTimeUint(lastResetTimeStamp);
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001205 });
Gunnar Millsc0557e12020-06-30 11:26:20 -05001206}
1207
1208/**
Corey Hardesty797d5da2022-04-26 17:54:52 +08001209 * @brief Retrieves the number of automatic boot Retry attempts allowed/left.
1210 *
1211 * The total number of automatic reboot retries allowed "RetryAttempts" and its
1212 * corresponding property "AttemptsLeft" that keeps track of the amount of
1213 * automatic retry attempts left are hosted in phosphor-state-manager through
1214 * dbus.
1215 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001216 * @param[in] asyncResp Shared pointer for generating response message.
Corey Hardesty797d5da2022-04-26 17:54:52 +08001217 *
1218 * @return None.
1219 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001220inline void getAutomaticRebootAttempts(
1221 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Corey Hardesty797d5da2022-04-26 17:54:52 +08001222{
1223 BMCWEB_LOG_DEBUG << "Get Automatic Retry policy";
1224
1225 sdbusplus::asio::getAllProperties(
1226 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
1227 "/xyz/openbmc_project/state/host0",
1228 "xyz.openbmc_project.Control.Boot.RebootAttempts",
Ed Tanousac106bf2023-06-07 09:24:59 -07001229 [asyncResp{asyncResp}](
1230 const boost::system::error_code& ec,
1231 const dbus::utility::DBusPropertiesMap& propertiesList) {
Corey Hardesty797d5da2022-04-26 17:54:52 +08001232 if (ec)
1233 {
1234 if (ec.value() != EBADR)
1235 {
1236 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07001237 messages::internalError(asyncResp->res);
Corey Hardesty797d5da2022-04-26 17:54:52 +08001238 }
1239 return;
1240 }
1241
1242 const uint32_t* attemptsLeft = nullptr;
1243 const uint32_t* retryAttempts = nullptr;
1244
1245 const bool success = sdbusplus::unpackPropertiesNoThrow(
1246 dbus_utils::UnpackErrorPrinter(), propertiesList, "AttemptsLeft",
1247 attemptsLeft, "RetryAttempts", retryAttempts);
1248
1249 if (!success)
1250 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001251 messages::internalError(asyncResp->res);
Corey Hardesty797d5da2022-04-26 17:54:52 +08001252 return;
1253 }
1254
1255 if (attemptsLeft != nullptr)
1256 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001257 asyncResp->res
1258 .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] =
Corey Hardesty797d5da2022-04-26 17:54:52 +08001259 *attemptsLeft;
1260 }
1261
1262 if (retryAttempts != nullptr)
1263 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001264 asyncResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] =
Corey Hardesty797d5da2022-04-26 17:54:52 +08001265 *retryAttempts;
1266 }
1267 });
1268}
1269
1270/**
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001271 * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
1272 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001273 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001274 *
1275 * @return None.
1276 */
Corey Hardesty797d5da2022-04-26 17:54:52 +08001277inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001278 getAutomaticRetryPolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001279{
1280 BMCWEB_LOG_DEBUG << "Get Automatic Retry policy";
1281
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001282 sdbusplus::asio::getProperty<bool>(
1283 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1284 "/xyz/openbmc_project/control/host0/auto_reboot",
1285 "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
Ed Tanousac106bf2023-06-07 09:24:59 -07001286 [asyncResp](const boost::system::error_code& ec,
1287 bool autoRebootEnabled) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001288 if (ec)
1289 {
Corey Hardesty797d5da2022-04-26 17:54:52 +08001290 if (ec.value() != EBADR)
1291 {
1292 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07001293 messages::internalError(asyncResp->res);
Corey Hardesty797d5da2022-04-26 17:54:52 +08001294 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001295 return;
1296 }
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001297
Ed Tanous002d39b2022-05-31 08:59:27 -07001298 BMCWEB_LOG_DEBUG << "Auto Reboot: " << autoRebootEnabled;
1299 if (autoRebootEnabled)
1300 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001301 asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001302 "RetryAttempts";
Ed Tanous002d39b2022-05-31 08:59:27 -07001303 }
1304 else
1305 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001306 asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
1307 "Disabled";
Ed Tanous002d39b2022-05-31 08:59:27 -07001308 }
Ed Tanousac106bf2023-06-07 09:24:59 -07001309 getAutomaticRebootAttempts(asyncResp);
Gunnar Mills69f35302020-05-17 16:06:31 -05001310
Ed Tanous002d39b2022-05-31 08:59:27 -07001311 // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
1312 // and RetryAttempts. OpenBMC only supports Disabled and
1313 // RetryAttempts.
Ed Tanousac106bf2023-06-07 09:24:59 -07001314 asyncResp->res
1315 .jsonValue["Boot"]["AutomaticRetryConfig@Redfish.AllowableValues"] =
1316 {"Disabled", "RetryAttempts"};
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001317 });
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001318}
1319
1320/**
Corey Hardesty797d5da2022-04-26 17:54:52 +08001321 * @brief Sets RetryAttempts
1322 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001323 * @param[in] asyncResp Shared pointer for generating response message.
Corey Hardesty797d5da2022-04-26 17:54:52 +08001324 * @param[in] retryAttempts "AutomaticRetryAttempts" from request.
1325 *
1326 *@return None.
1327 */
1328
Ed Tanousac106bf2023-06-07 09:24:59 -07001329inline void setAutomaticRetryAttempts(
1330 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1331 const uint32_t retryAttempts)
Corey Hardesty797d5da2022-04-26 17:54:52 +08001332{
1333 BMCWEB_LOG_DEBUG << "Set Automatic Retry Attempts.";
1334 crow::connections::systemBus->async_method_call(
Ed Tanousac106bf2023-06-07 09:24:59 -07001335 [asyncResp](const boost::system::error_code& ec) {
Corey Hardesty797d5da2022-04-26 17:54:52 +08001336 if (ec)
1337 {
1338 BMCWEB_LOG_ERROR
1339 << "DBUS response error: Set setAutomaticRetryAttempts" << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07001340 messages::internalError(asyncResp->res);
Corey Hardesty797d5da2022-04-26 17:54:52 +08001341 return;
1342 }
1343 },
1344 "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
1345 "org.freedesktop.DBus.Properties", "Set",
1346 "xyz.openbmc_project.Control.Boot.RebootAttempts", "RetryAttempts",
1347 std::variant<uint32_t>(retryAttempts));
1348}
1349
1350/**
George Liuc6a620f2020-04-10 17:18:11 +08001351 * @brief Retrieves power restore policy over DBUS.
1352 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001353 * @param[in] asyncResp Shared pointer for generating response message.
George Liuc6a620f2020-04-10 17:18:11 +08001354 *
1355 * @return None.
1356 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001357inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001358 getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
George Liuc6a620f2020-04-10 17:18:11 +08001359{
1360 BMCWEB_LOG_DEBUG << "Get power restore policy";
1361
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001362 sdbusplus::asio::getProperty<std::string>(
1363 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1364 "/xyz/openbmc_project/control/host0/power_restore_policy",
1365 "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
Ed Tanousac106bf2023-06-07 09:24:59 -07001366 [asyncResp](const boost::system::error_code& ec,
1367 const std::string& policy) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001368 if (ec)
1369 {
1370 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1371 return;
1372 }
George Liuc6a620f2020-04-10 17:18:11 +08001373
Ed Tanous002d39b2022-05-31 08:59:27 -07001374 const boost::container::flat_map<std::string, std::string> policyMaps = {
1375 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn",
1376 "AlwaysOn"},
1377 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff",
1378 "AlwaysOff"},
1379 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore",
1380 "LastState"},
1381 // Return `AlwaysOff` when power restore policy set to "None"
1382 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None",
1383 "AlwaysOff"}};
George Liuc6a620f2020-04-10 17:18:11 +08001384
Ed Tanous002d39b2022-05-31 08:59:27 -07001385 auto policyMapsIt = policyMaps.find(policy);
1386 if (policyMapsIt == policyMaps.end())
1387 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001388 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001389 return;
1390 }
George Liuc6a620f2020-04-10 17:18:11 +08001391
Ed Tanousac106bf2023-06-07 09:24:59 -07001392 asyncResp->res.jsonValue["PowerRestorePolicy"] = policyMapsIt->second;
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001393 });
George Liuc6a620f2020-04-10 17:18:11 +08001394}
1395
1396/**
Ali Ahmed19817712021-06-29 17:01:52 -05001397 * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not
1398 * TPM is required for booting the host.
1399 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001400 * @param[in] asyncResp Shared pointer for generating response message.
Ali Ahmed19817712021-06-29 17:01:52 -05001401 *
1402 * @return None.
1403 */
1404inline void getTrustedModuleRequiredToBoot(
Ed Tanousac106bf2023-06-07 09:24:59 -07001405 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Ali Ahmed19817712021-06-29 17:01:52 -05001406{
1407 BMCWEB_LOG_DEBUG << "Get TPM required to boot.";
George Liue99073f2022-12-09 11:06:16 +08001408 constexpr std::array<std::string_view, 1> interfaces = {
1409 "xyz.openbmc_project.Control.TPM.Policy"};
1410 dbus::utility::getSubTree(
1411 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07001412 [asyncResp](const boost::system::error_code& ec,
1413 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001414 if (ec)
1415 {
1416 BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree"
1417 << ec;
1418 // This is an optional D-Bus object so just return if
1419 // error occurs
1420 return;
1421 }
1422 if (subtree.empty())
1423 {
1424 // As noted above, this is an optional interface so just return
1425 // if there is no instance found
1426 return;
1427 }
1428
1429 /* When there is more than one TPMEnable object... */
1430 if (subtree.size() > 1)
1431 {
1432 BMCWEB_LOG_DEBUG
1433 << "DBUS response has more than 1 TPM Enable object:"
1434 << subtree.size();
1435 // Throw an internal Error and return
Ed Tanousac106bf2023-06-07 09:24:59 -07001436 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001437 return;
1438 }
1439
1440 // Make sure the Dbus response map has a service and objectPath
1441 // field
1442 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1443 {
1444 BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07001445 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001446 return;
1447 }
1448
1449 const std::string& path = subtree[0].first;
1450 const std::string& serv = subtree[0].second.begin()->first;
1451
1452 // Valid TPM Enable object found, now reading the current value
1453 sdbusplus::asio::getProperty<bool>(
1454 *crow::connections::systemBus, serv, path,
1455 "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
Ed Tanousac106bf2023-06-07 09:24:59 -07001456 [asyncResp](const boost::system::error_code& ec2,
1457 bool tpmRequired) {
Ed Tanous8a592812022-06-04 09:06:59 -07001458 if (ec2)
Ali Ahmed19817712021-06-29 17:01:52 -05001459 {
Ed Tanous002d39b2022-05-31 08:59:27 -07001460 BMCWEB_LOG_DEBUG << "D-BUS response error on TPM.Policy Get"
Ed Tanous8a592812022-06-04 09:06:59 -07001461 << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -07001462 messages::internalError(asyncResp->res);
Ali Ahmed19817712021-06-29 17:01:52 -05001463 return;
1464 }
1465
Ed Tanous002d39b2022-05-31 08:59:27 -07001466 if (tpmRequired)
Ali Ahmed19817712021-06-29 17:01:52 -05001467 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001468 asyncResp->res
1469 .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001470 "Required";
Ali Ahmed19817712021-06-29 17:01:52 -05001471 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001472 else
1473 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001474 asyncResp->res
1475 .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001476 "Disabled";
1477 }
1478 });
George Liue99073f2022-12-09 11:06:16 +08001479 });
Ali Ahmed19817712021-06-29 17:01:52 -05001480}
1481
1482/**
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001483 * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not
1484 * TPM is required for booting the host.
1485 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001486 * @param[in] asyncResp Shared pointer for generating response message.
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001487 * @param[in] tpmRequired Value to set TPM Required To Boot property to.
1488 *
1489 * @return None.
1490 */
1491inline void setTrustedModuleRequiredToBoot(
Ed Tanousac106bf2023-06-07 09:24:59 -07001492 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const bool tpmRequired)
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001493{
1494 BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot.";
George Liue99073f2022-12-09 11:06:16 +08001495 constexpr std::array<std::string_view, 1> interfaces = {
1496 "xyz.openbmc_project.Control.TPM.Policy"};
1497 dbus::utility::getSubTree(
1498 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07001499 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +08001500 tpmRequired](const boost::system::error_code& ec,
1501 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001502 if (ec)
1503 {
1504 BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree"
1505 << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07001506 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001507 return;
1508 }
1509 if (subtree.empty())
1510 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001511 messages::propertyValueNotInList(asyncResp->res, "ComputerSystem",
Ed Tanous002d39b2022-05-31 08:59:27 -07001512 "TrustedModuleRequiredToBoot");
1513 return;
1514 }
1515
1516 /* When there is more than one TPMEnable object... */
1517 if (subtree.size() > 1)
1518 {
1519 BMCWEB_LOG_DEBUG
1520 << "DBUS response has more than 1 TPM Enable object:"
1521 << subtree.size();
1522 // Throw an internal Error and return
Ed Tanousac106bf2023-06-07 09:24:59 -07001523 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001524 return;
1525 }
1526
1527 // Make sure the Dbus response map has a service and objectPath
1528 // field
1529 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1530 {
1531 BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07001532 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001533 return;
1534 }
1535
1536 const std::string& path = subtree[0].first;
1537 const std::string& serv = subtree[0].second.begin()->first;
1538
1539 if (serv.empty())
1540 {
1541 BMCWEB_LOG_DEBUG << "TPM.Policy service mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07001542 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001543 return;
1544 }
1545
1546 // Valid TPM Enable object found, now setting the value
1547 crow::connections::systemBus->async_method_call(
Ed Tanousac106bf2023-06-07 09:24:59 -07001548 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07001549 if (ec2)
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001550 {
1551 BMCWEB_LOG_DEBUG
Ed Tanous002d39b2022-05-31 08:59:27 -07001552 << "DBUS response error: Set TrustedModuleRequiredToBoot"
Ed Tanous8a592812022-06-04 09:06:59 -07001553 << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -07001554 messages::internalError(asyncResp->res);
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001555 return;
1556 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001557 BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot done.";
1558 },
1559 serv, path, "org.freedesktop.DBus.Properties", "Set",
1560 "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
1561 dbus::utility::DbusVariantType(tpmRequired));
George Liue99073f2022-12-09 11:06:16 +08001562 });
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001563}
1564
1565/**
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301566 * @brief Sets boot properties into DBUS object(s).
1567 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001568 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001569 * @param[in] bootType The boot type to set.
1570 * @return Integer error code.
1571 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001572inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001573 const std::optional<std::string>& bootType)
1574{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001575 std::string bootTypeStr;
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001576
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001577 if (!bootType)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001578 {
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001579 return;
1580 }
1581
1582 // Source target specified
1583 BMCWEB_LOG_DEBUG << "Boot type: " << *bootType;
1584 // Figure out which DBUS interface and property to use
1585 if (*bootType == "Legacy")
1586 {
1587 bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy";
1588 }
1589 else if (*bootType == "UEFI")
1590 {
1591 bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI";
1592 }
1593 else
1594 {
1595 BMCWEB_LOG_DEBUG << "Invalid property value for "
1596 "BootSourceOverrideMode: "
1597 << *bootType;
Ed Tanousac106bf2023-06-07 09:24:59 -07001598 messages::propertyValueNotInList(asyncResp->res, *bootType,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001599 "BootSourceOverrideMode");
1600 return;
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001601 }
1602
1603 // Act on validated parameters
1604 BMCWEB_LOG_DEBUG << "DBUS boot type: " << bootTypeStr;
1605
1606 crow::connections::systemBus->async_method_call(
Ed Tanousac106bf2023-06-07 09:24:59 -07001607 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001608 if (ec)
1609 {
1610 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1611 if (ec.value() == boost::asio::error::host_unreachable)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001612 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001613 messages::resourceNotFound(asyncResp->res, "Set", "BootType");
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001614 return;
1615 }
Ed Tanousac106bf2023-06-07 09:24:59 -07001616 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001617 return;
1618 }
1619 BMCWEB_LOG_DEBUG << "Boot type update done.";
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001620 },
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001621 "xyz.openbmc_project.Settings",
1622 "/xyz/openbmc_project/control/host0/boot",
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001623 "org.freedesktop.DBus.Properties", "Set",
1624 "xyz.openbmc_project.Control.Boot.Type", "BootType",
Ed Tanous168e20c2021-12-13 14:39:53 -08001625 dbus::utility::DbusVariantType(bootTypeStr));
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001626}
1627
1628/**
1629 * @brief Sets boot properties into DBUS object(s).
1630 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001631 * @param[in] asyncResp Shared pointer for generating response
1632 * message.
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001633 * @param[in] bootType The boot type to set.
1634 * @return Integer error code.
1635 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001636inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001637 const std::optional<std::string>& bootEnable)
1638{
1639 if (!bootEnable)
1640 {
1641 return;
1642 }
1643 // Source target specified
1644 BMCWEB_LOG_DEBUG << "Boot enable: " << *bootEnable;
1645
1646 bool bootOverrideEnable = false;
1647 bool bootOverridePersistent = false;
1648 // Figure out which DBUS interface and property to use
1649 if (*bootEnable == "Disabled")
1650 {
1651 bootOverrideEnable = false;
1652 }
1653 else if (*bootEnable == "Once")
1654 {
1655 bootOverrideEnable = true;
1656 bootOverridePersistent = false;
1657 }
1658 else if (*bootEnable == "Continuous")
1659 {
1660 bootOverrideEnable = true;
1661 bootOverridePersistent = true;
1662 }
1663 else
1664 {
George Liu0fda0f12021-11-16 10:06:17 +08001665 BMCWEB_LOG_DEBUG
1666 << "Invalid property value for BootSourceOverrideEnabled: "
1667 << *bootEnable;
Ed Tanousac106bf2023-06-07 09:24:59 -07001668 messages::propertyValueNotInList(asyncResp->res, *bootEnable,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001669 "BootSourceOverrideEnabled");
1670 return;
1671 }
1672
1673 // Act on validated parameters
1674 BMCWEB_LOG_DEBUG << "DBUS boot override enable: " << bootOverrideEnable;
1675
1676 crow::connections::systemBus->async_method_call(
Ed Tanousac106bf2023-06-07 09:24:59 -07001677 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07001678 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07001679 {
Ed Tanous8a592812022-06-04 09:06:59 -07001680 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -07001681 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001682 return;
1683 }
1684 BMCWEB_LOG_DEBUG << "Boot override enable update done.";
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001685 },
1686 "xyz.openbmc_project.Settings",
1687 "/xyz/openbmc_project/control/host0/boot",
1688 "org.freedesktop.DBus.Properties", "Set",
1689 "xyz.openbmc_project.Object.Enable", "Enabled",
Ed Tanous168e20c2021-12-13 14:39:53 -08001690 dbus::utility::DbusVariantType(bootOverrideEnable));
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001691
1692 if (!bootOverrideEnable)
1693 {
1694 return;
1695 }
1696
1697 // In case boot override is enabled we need to set correct value for the
1698 // 'one_time' enable DBus interface
1699 BMCWEB_LOG_DEBUG << "DBUS boot override persistent: "
1700 << bootOverridePersistent;
1701
1702 crow::connections::systemBus->async_method_call(
Ed Tanousac106bf2023-06-07 09:24:59 -07001703 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001704 if (ec)
1705 {
1706 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07001707 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001708 return;
1709 }
1710 BMCWEB_LOG_DEBUG << "Boot one_time update done.";
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001711 },
1712 "xyz.openbmc_project.Settings",
1713 "/xyz/openbmc_project/control/host0/boot/one_time",
1714 "org.freedesktop.DBus.Properties", "Set",
1715 "xyz.openbmc_project.Object.Enable", "Enabled",
Ed Tanous168e20c2021-12-13 14:39:53 -08001716 dbus::utility::DbusVariantType(!bootOverridePersistent));
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001717}
1718
1719/**
1720 * @brief Sets boot properties into DBUS object(s).
1721 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001722 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301723 * @param[in] bootSource The boot source to set.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301724 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001725 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301726 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001727inline void
1728 setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1729 const std::optional<std::string>& bootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301730{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001731 std::string bootSourceStr;
1732 std::string bootModeStr;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001733
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001734 if (!bootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301735 {
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001736 return;
1737 }
1738
1739 // Source target specified
1740 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource;
1741 // Figure out which DBUS interface and property to use
Ed Tanousac106bf2023-06-07 09:24:59 -07001742 if (assignBootParameters(asyncResp, *bootSource, bootSourceStr,
1743 bootModeStr) != 0)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001744 {
1745 BMCWEB_LOG_DEBUG
1746 << "Invalid property value for BootSourceOverrideTarget: "
1747 << *bootSource;
Ed Tanousac106bf2023-06-07 09:24:59 -07001748 messages::propertyValueNotInList(asyncResp->res, *bootSource,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001749 "BootSourceTargetOverride");
1750 return;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001751 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301752
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001753 // Act on validated parameters
1754 BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
1755 BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001756
1757 crow::connections::systemBus->async_method_call(
Ed Tanousac106bf2023-06-07 09:24:59 -07001758 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001759 if (ec)
1760 {
1761 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07001762 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001763 return;
1764 }
1765 BMCWEB_LOG_DEBUG << "Boot source update done.";
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001766 },
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001767 "xyz.openbmc_project.Settings",
1768 "/xyz/openbmc_project/control/host0/boot",
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001769 "org.freedesktop.DBus.Properties", "Set",
1770 "xyz.openbmc_project.Control.Boot.Source", "BootSource",
Ed Tanous168e20c2021-12-13 14:39:53 -08001771 dbus::utility::DbusVariantType(bootSourceStr));
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001772
1773 crow::connections::systemBus->async_method_call(
Ed Tanousac106bf2023-06-07 09:24:59 -07001774 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001775 if (ec)
1776 {
1777 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07001778 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001779 return;
1780 }
1781 BMCWEB_LOG_DEBUG << "Boot mode update done.";
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001782 },
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001783 "xyz.openbmc_project.Settings",
1784 "/xyz/openbmc_project/control/host0/boot",
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001785 "org.freedesktop.DBus.Properties", "Set",
1786 "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
Ed Tanous168e20c2021-12-13 14:39:53 -08001787 dbus::utility::DbusVariantType(bootModeStr));
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001788}
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001789
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001790/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001791 * @brief Sets Boot source override properties.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301792 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001793 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301794 * @param[in] bootSource The boot source from incoming RF request.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001795 * @param[in] bootType The boot type from incoming RF request.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301796 * @param[in] bootEnable The boot override enable from incoming RF request.
1797 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001798 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301799 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001800
Ed Tanousac106bf2023-06-07 09:24:59 -07001801inline void
1802 setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1803 const std::optional<std::string>& bootSource,
1804 const std::optional<std::string>& bootType,
1805 const std::optional<std::string>& bootEnable)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301806{
1807 BMCWEB_LOG_DEBUG << "Set boot information.";
1808
Ed Tanousac106bf2023-06-07 09:24:59 -07001809 setBootModeOrSource(asyncResp, bootSource);
1810 setBootType(asyncResp, bootType);
1811 setBootEnable(asyncResp, bootEnable);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301812}
1813
George Liuc6a620f2020-04-10 17:18:11 +08001814/**
Gunnar Mills98e386e2020-10-30 14:58:09 -05001815 * @brief Sets AssetTag
1816 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001817 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Mills98e386e2020-10-30 14:58:09 -05001818 * @param[in] assetTag "AssetTag" from request.
1819 *
1820 * @return None.
1821 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001822inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Gunnar Mills98e386e2020-10-30 14:58:09 -05001823 const std::string& assetTag)
1824{
George Liue99073f2022-12-09 11:06:16 +08001825 constexpr std::array<std::string_view, 1> interfaces = {
1826 "xyz.openbmc_project.Inventory.Item.System"};
1827 dbus::utility::getSubTree(
1828 "/xyz/openbmc_project/inventory", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07001829 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +08001830 assetTag](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08001831 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001832 if (ec)
1833 {
1834 BMCWEB_LOG_DEBUG << "D-Bus response error on GetSubTree " << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07001835 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001836 return;
1837 }
1838 if (subtree.empty())
1839 {
1840 BMCWEB_LOG_DEBUG << "Can't find system D-Bus object!";
Ed Tanousac106bf2023-06-07 09:24:59 -07001841 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001842 return;
1843 }
1844 // Assume only 1 system D-Bus object
1845 // Throw an error if there is more than 1
1846 if (subtree.size() > 1)
1847 {
1848 BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus object!";
Ed Tanousac106bf2023-06-07 09:24:59 -07001849 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001850 return;
1851 }
1852 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1853 {
1854 BMCWEB_LOG_DEBUG << "Asset Tag Set mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07001855 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001856 return;
1857 }
Gunnar Mills98e386e2020-10-30 14:58:09 -05001858
Ed Tanous002d39b2022-05-31 08:59:27 -07001859 const std::string& path = subtree[0].first;
1860 const std::string& service = subtree[0].second.begin()->first;
Gunnar Mills98e386e2020-10-30 14:58:09 -05001861
Ed Tanous002d39b2022-05-31 08:59:27 -07001862 if (service.empty())
1863 {
1864 BMCWEB_LOG_DEBUG << "Asset Tag Set service mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07001865 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001866 return;
1867 }
1868
1869 crow::connections::systemBus->async_method_call(
Ed Tanousac106bf2023-06-07 09:24:59 -07001870 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001871 if (ec2)
Gunnar Mills98e386e2020-10-30 14:58:09 -05001872 {
Ed Tanous002d39b2022-05-31 08:59:27 -07001873 BMCWEB_LOG_DEBUG << "D-Bus response error on AssetTag Set "
1874 << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -07001875 messages::internalError(asyncResp->res);
Gunnar Mills98e386e2020-10-30 14:58:09 -05001876 return;
1877 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001878 },
1879 service, path, "org.freedesktop.DBus.Properties", "Set",
1880 "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag",
1881 dbus::utility::DbusVariantType(assetTag));
George Liue99073f2022-12-09 11:06:16 +08001882 });
Gunnar Mills98e386e2020-10-30 14:58:09 -05001883}
1884
1885/**
Gunnar Mills69f35302020-05-17 16:06:31 -05001886 * @brief Sets automaticRetry (Auto Reboot)
1887 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001888 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Mills69f35302020-05-17 16:06:31 -05001889 * @param[in] automaticRetryConfig "AutomaticRetryConfig" from request.
1890 *
1891 * @return None.
1892 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001893inline void
1894 setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1895 const std::string& automaticRetryConfig)
Gunnar Mills69f35302020-05-17 16:06:31 -05001896{
1897 BMCWEB_LOG_DEBUG << "Set Automatic Retry.";
1898
1899 // OpenBMC only supports "Disabled" and "RetryAttempts".
Ed Tanous543f4402022-01-06 13:12:53 -08001900 bool autoRebootEnabled = false;
Gunnar Mills69f35302020-05-17 16:06:31 -05001901
1902 if (automaticRetryConfig == "Disabled")
1903 {
1904 autoRebootEnabled = false;
1905 }
1906 else if (automaticRetryConfig == "RetryAttempts")
1907 {
1908 autoRebootEnabled = true;
1909 }
1910 else
1911 {
George Liu0fda0f12021-11-16 10:06:17 +08001912 BMCWEB_LOG_DEBUG << "Invalid property value for AutomaticRetryConfig: "
Gunnar Mills69f35302020-05-17 16:06:31 -05001913 << automaticRetryConfig;
Ed Tanousac106bf2023-06-07 09:24:59 -07001914 messages::propertyValueNotInList(asyncResp->res, automaticRetryConfig,
Gunnar Mills69f35302020-05-17 16:06:31 -05001915 "AutomaticRetryConfig");
1916 return;
1917 }
1918
1919 crow::connections::systemBus->async_method_call(
Ed Tanousac106bf2023-06-07 09:24:59 -07001920 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001921 if (ec)
1922 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001923 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001924 return;
1925 }
Gunnar Mills69f35302020-05-17 16:06:31 -05001926 },
1927 "xyz.openbmc_project.Settings",
1928 "/xyz/openbmc_project/control/host0/auto_reboot",
1929 "org.freedesktop.DBus.Properties", "Set",
1930 "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
Ed Tanous168e20c2021-12-13 14:39:53 -08001931 dbus::utility::DbusVariantType(autoRebootEnabled));
Gunnar Mills69f35302020-05-17 16:06:31 -05001932}
1933
1934/**
George Liuc6a620f2020-04-10 17:18:11 +08001935 * @brief Sets power restore policy properties.
1936 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001937 * @param[in] asyncResp Shared pointer for generating response message.
George Liuc6a620f2020-04-10 17:18:11 +08001938 * @param[in] policy power restore policy properties from request.
1939 *
1940 * @return None.
1941 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001942inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001943 setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
zhanghch058d1b46d2021-04-01 11:18:24 +08001944 const std::string& policy)
George Liuc6a620f2020-04-10 17:18:11 +08001945{
1946 BMCWEB_LOG_DEBUG << "Set power restore policy.";
1947
1948 const boost::container::flat_map<std::string, std::string> policyMaps = {
George Liu0fda0f12021-11-16 10:06:17 +08001949 {"AlwaysOn",
1950 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn"},
1951 {"AlwaysOff",
1952 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff"},
1953 {"LastState",
1954 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore"}};
George Liuc6a620f2020-04-10 17:18:11 +08001955
1956 std::string powerRestorPolicy;
1957
Gunnar Mills4e69c902021-01-05 19:50:11 -06001958 auto policyMapsIt = policyMaps.find(policy);
George Liuc6a620f2020-04-10 17:18:11 +08001959 if (policyMapsIt == policyMaps.end())
1960 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001961 messages::propertyValueNotInList(asyncResp->res, policy,
Gunnar Mills4e69c902021-01-05 19:50:11 -06001962 "PowerRestorePolicy");
George Liuc6a620f2020-04-10 17:18:11 +08001963 return;
1964 }
1965
1966 powerRestorPolicy = policyMapsIt->second;
1967
1968 crow::connections::systemBus->async_method_call(
Ed Tanousac106bf2023-06-07 09:24:59 -07001969 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001970 if (ec)
1971 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001972 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001973 return;
1974 }
George Liuc6a620f2020-04-10 17:18:11 +08001975 },
1976 "xyz.openbmc_project.Settings",
1977 "/xyz/openbmc_project/control/host0/power_restore_policy",
1978 "org.freedesktop.DBus.Properties", "Set",
1979 "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
Ed Tanous168e20c2021-12-13 14:39:53 -08001980 dbus::utility::DbusVariantType(powerRestorPolicy));
George Liuc6a620f2020-04-10 17:18:11 +08001981}
1982
AppaRao Pulia6349912019-10-18 17:16:08 +05301983#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1984/**
1985 * @brief Retrieves provisioning status
1986 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001987 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
AppaRao Pulia6349912019-10-18 17:16:08 +05301988 *
1989 * @return None.
1990 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001991inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> asyncResp)
AppaRao Pulia6349912019-10-18 17:16:08 +05301992{
1993 BMCWEB_LOG_DEBUG << "Get OEM information.";
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02001994 sdbusplus::asio::getAllProperties(
1995 *crow::connections::systemBus, "xyz.openbmc_project.PFR.Manager",
1996 "/xyz/openbmc_project/pfr", "xyz.openbmc_project.PFR.Attributes",
Ed Tanousac106bf2023-06-07 09:24:59 -07001997 [asyncResp](const boost::system::error_code& ec,
1998 const dbus::utility::DBusPropertiesMap& propertiesList) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001999 nlohmann::json& oemPFR =
Ed Tanousac106bf2023-06-07 09:24:59 -07002000 asyncResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
2001 asyncResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07002002 "#OemComputerSystem.OpenBmc";
2003 oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning";
James Feist50626f42020-09-23 14:40:47 -07002004
Ed Tanous002d39b2022-05-31 08:59:27 -07002005 if (ec)
2006 {
2007 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2008 // not an error, don't have to have the interface
2009 oemPFR["ProvisioningStatus"] = "NotProvisioned";
2010 return;
2011 }
2012
2013 const bool* provState = nullptr;
2014 const bool* lockState = nullptr;
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002015
2016 const bool success = sdbusplus::unpackPropertiesNoThrow(
Jiaqing Zhao0d4befa2022-08-19 15:14:32 +08002017 dbus_utils::UnpackErrorPrinter(), propertiesList, "UfmProvisioned",
2018 provState, "UfmLocked", lockState);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002019
2020 if (!success)
Ed Tanous002d39b2022-05-31 08:59:27 -07002021 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002022 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002023 return;
Ed Tanous002d39b2022-05-31 08:59:27 -07002024 }
AppaRao Pulia6349912019-10-18 17:16:08 +05302025
Ed Tanous002d39b2022-05-31 08:59:27 -07002026 if ((provState == nullptr) || (lockState == nullptr))
2027 {
2028 BMCWEB_LOG_DEBUG << "Unable to get PFR attributes.";
Ed Tanousac106bf2023-06-07 09:24:59 -07002029 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002030 return;
2031 }
AppaRao Pulia6349912019-10-18 17:16:08 +05302032
Ed Tanous002d39b2022-05-31 08:59:27 -07002033 if (*provState == true)
2034 {
2035 if (*lockState == true)
AppaRao Pulia6349912019-10-18 17:16:08 +05302036 {
Ed Tanous002d39b2022-05-31 08:59:27 -07002037 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
AppaRao Pulia6349912019-10-18 17:16:08 +05302038 }
2039 else
2040 {
Ed Tanous002d39b2022-05-31 08:59:27 -07002041 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
AppaRao Pulia6349912019-10-18 17:16:08 +05302042 }
Ed Tanous002d39b2022-05-31 08:59:27 -07002043 }
2044 else
2045 {
2046 oemPFR["ProvisioningStatus"] = "NotProvisioned";
2047 }
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002048 });
AppaRao Pulia6349912019-10-18 17:16:08 +05302049}
2050#endif
2051
Santosh Puranik491d8ee2019-02-06 19:46:56 +05302052/**
Chris Cain3a2d04242021-05-28 16:57:10 -05002053 * @brief Translate the PowerMode to a response message.
2054 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002055 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain3a2d04242021-05-28 16:57:10 -05002056 * @param[in] modeValue PowerMode value to be translated
2057 *
2058 * @return None.
2059 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002060inline void
2061 translatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2062 const std::string& modeValue)
Chris Cain3a2d04242021-05-28 16:57:10 -05002063{
George Liu0fda0f12021-11-16 10:06:17 +08002064 if (modeValue == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static")
Chris Cain3a2d04242021-05-28 16:57:10 -05002065 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002066 asyncResp->res.jsonValue["PowerMode"] = "Static";
Chris Cain3a2d04242021-05-28 16:57:10 -05002067 }
George Liu0fda0f12021-11-16 10:06:17 +08002068 else if (
2069 modeValue ==
2070 "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance")
Chris Cain3a2d04242021-05-28 16:57:10 -05002071 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002072 asyncResp->res.jsonValue["PowerMode"] = "MaximumPerformance";
Chris Cain3a2d04242021-05-28 16:57:10 -05002073 }
George Liu0fda0f12021-11-16 10:06:17 +08002074 else if (modeValue ==
2075 "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving")
Chris Cain3a2d04242021-05-28 16:57:10 -05002076 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002077 asyncResp->res.jsonValue["PowerMode"] = "PowerSaving";
Chris Cain3a2d04242021-05-28 16:57:10 -05002078 }
George Liu0fda0f12021-11-16 10:06:17 +08002079 else if (modeValue ==
2080 "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM")
Chris Cain3a2d04242021-05-28 16:57:10 -05002081 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002082 asyncResp->res.jsonValue["PowerMode"] = "OEM";
Chris Cain3a2d04242021-05-28 16:57:10 -05002083 }
2084 else
2085 {
2086 // Any other values would be invalid
2087 BMCWEB_LOG_DEBUG << "PowerMode value was not valid: " << modeValue;
Ed Tanousac106bf2023-06-07 09:24:59 -07002088 messages::internalError(asyncResp->res);
Chris Cain3a2d04242021-05-28 16:57:10 -05002089 }
2090}
2091
2092/**
2093 * @brief Retrieves system power mode
2094 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002095 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain3a2d04242021-05-28 16:57:10 -05002096 *
2097 * @return None.
2098 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002099inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Chris Cain3a2d04242021-05-28 16:57:10 -05002100{
2101 BMCWEB_LOG_DEBUG << "Get power mode.";
2102
2103 // Get Power Mode object path:
George Liue99073f2022-12-09 11:06:16 +08002104 constexpr std::array<std::string_view, 1> interfaces = {
2105 "xyz.openbmc_project.Control.Power.Mode"};
2106 dbus::utility::getSubTree(
2107 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002108 [asyncResp](const boost::system::error_code& ec,
2109 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002110 if (ec)
2111 {
2112 BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree "
2113 << ec;
2114 // This is an optional D-Bus object so just return if
2115 // error occurs
2116 return;
2117 }
2118 if (subtree.empty())
2119 {
2120 // As noted above, this is an optional interface so just return
2121 // if there is no instance found
2122 return;
2123 }
2124 if (subtree.size() > 1)
2125 {
2126 // More then one PowerMode object is not supported and is an
2127 // error
2128 BMCWEB_LOG_DEBUG
2129 << "Found more than 1 system D-Bus Power.Mode objects: "
2130 << subtree.size();
Ed Tanousac106bf2023-06-07 09:24:59 -07002131 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002132 return;
2133 }
2134 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2135 {
2136 BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07002137 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002138 return;
2139 }
2140 const std::string& path = subtree[0].first;
2141 const std::string& service = subtree[0].second.begin()->first;
2142 if (service.empty())
2143 {
2144 BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07002145 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002146 return;
2147 }
2148 // Valid Power Mode object found, now read the current value
2149 sdbusplus::asio::getProperty<std::string>(
2150 *crow::connections::systemBus, service, path,
2151 "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
Ed Tanousac106bf2023-06-07 09:24:59 -07002152 [asyncResp](const boost::system::error_code& ec2,
2153 const std::string& pmode) {
Ed Tanous8a592812022-06-04 09:06:59 -07002154 if (ec2)
Chris Cain3a2d04242021-05-28 16:57:10 -05002155 {
Ed Tanous002d39b2022-05-31 08:59:27 -07002156 BMCWEB_LOG_DEBUG << "DBUS response error on PowerMode Get: "
Ed Tanous8a592812022-06-04 09:06:59 -07002157 << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -07002158 messages::internalError(asyncResp->res);
Chris Cain3a2d04242021-05-28 16:57:10 -05002159 return;
2160 }
Chris Cain3a2d04242021-05-28 16:57:10 -05002161
Ed Tanousac106bf2023-06-07 09:24:59 -07002162 asyncResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = {
Ed Tanous002d39b2022-05-31 08:59:27 -07002163 "Static", "MaximumPerformance", "PowerSaving"};
Chris Cain3a2d04242021-05-28 16:57:10 -05002164
Ed Tanous002d39b2022-05-31 08:59:27 -07002165 BMCWEB_LOG_DEBUG << "Current power mode: " << pmode;
Ed Tanousac106bf2023-06-07 09:24:59 -07002166 translatePowerMode(asyncResp, pmode);
Ed Tanous002d39b2022-05-31 08:59:27 -07002167 });
George Liue99073f2022-12-09 11:06:16 +08002168 });
Chris Cain3a2d04242021-05-28 16:57:10 -05002169}
2170
2171/**
2172 * @brief Validate the specified mode is valid and return the PowerMode
2173 * name associated with that string
2174 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002175 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain3a2d04242021-05-28 16:57:10 -05002176 * @param[in] modeString String representing the desired PowerMode
2177 *
2178 * @return PowerMode value or empty string if mode is not valid
2179 */
2180inline std::string
Ed Tanousac106bf2023-06-07 09:24:59 -07002181 validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Chris Cain3a2d04242021-05-28 16:57:10 -05002182 const std::string& modeString)
2183{
2184 std::string mode;
2185
2186 if (modeString == "Static")
2187 {
2188 mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static";
2189 }
2190 else if (modeString == "MaximumPerformance")
2191 {
George Liu0fda0f12021-11-16 10:06:17 +08002192 mode =
2193 "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance";
Chris Cain3a2d04242021-05-28 16:57:10 -05002194 }
2195 else if (modeString == "PowerSaving")
2196 {
2197 mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving";
2198 }
2199 else
2200 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002201 messages::propertyValueNotInList(asyncResp->res, modeString,
2202 "PowerMode");
Chris Cain3a2d04242021-05-28 16:57:10 -05002203 }
2204 return mode;
2205}
2206
2207/**
2208 * @brief Sets system power mode.
2209 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002210 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain3a2d04242021-05-28 16:57:10 -05002211 * @param[in] pmode System power mode from request.
2212 *
2213 * @return None.
2214 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002215inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Chris Cain3a2d04242021-05-28 16:57:10 -05002216 const std::string& pmode)
2217{
2218 BMCWEB_LOG_DEBUG << "Set power mode.";
2219
Ed Tanousac106bf2023-06-07 09:24:59 -07002220 std::string powerMode = validatePowerMode(asyncResp, pmode);
Chris Cain3a2d04242021-05-28 16:57:10 -05002221 if (powerMode.empty())
2222 {
2223 return;
2224 }
2225
2226 // Get Power Mode object path:
George Liue99073f2022-12-09 11:06:16 +08002227 constexpr std::array<std::string_view, 1> interfaces = {
2228 "xyz.openbmc_project.Control.Power.Mode"};
2229 dbus::utility::getSubTree(
2230 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002231 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +08002232 powerMode](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08002233 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002234 if (ec)
2235 {
2236 BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree "
2237 << ec;
2238 // This is an optional D-Bus object, but user attempted to patch
Ed Tanousac106bf2023-06-07 09:24:59 -07002239 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002240 return;
2241 }
2242 if (subtree.empty())
2243 {
2244 // This is an optional D-Bus object, but user attempted to patch
Ed Tanousac106bf2023-06-07 09:24:59 -07002245 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
Ed Tanous002d39b2022-05-31 08:59:27 -07002246 "PowerMode");
2247 return;
2248 }
2249 if (subtree.size() > 1)
2250 {
2251 // More then one PowerMode object is not supported and is an
2252 // error
2253 BMCWEB_LOG_DEBUG
2254 << "Found more than 1 system D-Bus Power.Mode objects: "
2255 << subtree.size();
Ed Tanousac106bf2023-06-07 09:24:59 -07002256 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002257 return;
2258 }
2259 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2260 {
2261 BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07002262 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002263 return;
2264 }
2265 const std::string& path = subtree[0].first;
2266 const std::string& service = subtree[0].second.begin()->first;
2267 if (service.empty())
2268 {
2269 BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07002270 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002271 return;
2272 }
2273
2274 BMCWEB_LOG_DEBUG << "Setting power mode(" << powerMode << ") -> "
2275 << path;
2276
2277 // Set the Power Mode property
2278 crow::connections::systemBus->async_method_call(
Ed Tanousac106bf2023-06-07 09:24:59 -07002279 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002280 if (ec2)
Chris Cain3a2d04242021-05-28 16:57:10 -05002281 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002282 messages::internalError(asyncResp->res);
Chris Cain3a2d04242021-05-28 16:57:10 -05002283 return;
2284 }
Ed Tanous002d39b2022-05-31 08:59:27 -07002285 },
2286 service, path, "org.freedesktop.DBus.Properties", "Set",
2287 "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
2288 dbus::utility::DbusVariantType(powerMode));
George Liue99073f2022-12-09 11:06:16 +08002289 });
Chris Cain3a2d04242021-05-28 16:57:10 -05002290}
2291
2292/**
Yong Li51709ff2019-09-30 14:13:04 +08002293 * @brief Translates watchdog timeout action DBUS property value to redfish.
2294 *
2295 * @param[in] dbusAction The watchdog timeout action in D-BUS.
2296 *
2297 * @return Returns as a string, the timeout action in Redfish terms. If
2298 * translation cannot be done, returns an empty string.
2299 */
Ed Tanous23a21a12020-07-25 04:45:05 +00002300inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
Yong Li51709ff2019-09-30 14:13:04 +08002301{
2302 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
2303 {
2304 return "None";
2305 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002306 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
Yong Li51709ff2019-09-30 14:13:04 +08002307 {
2308 return "ResetSystem";
2309 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002310 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
Yong Li51709ff2019-09-30 14:13:04 +08002311 {
2312 return "PowerDown";
2313 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002314 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
Yong Li51709ff2019-09-30 14:13:04 +08002315 {
2316 return "PowerCycle";
2317 }
2318
2319 return "";
2320}
2321
2322/**
Yong Lic45f0082019-10-10 14:19:01 +08002323 *@brief Translates timeout action from Redfish to DBUS property value.
2324 *
2325 *@param[in] rfAction The timeout action in Redfish.
2326 *
2327 *@return Returns as a string, the time_out action as expected by DBUS.
2328 *If translation cannot be done, returns an empty string.
2329 */
2330
Ed Tanous23a21a12020-07-25 04:45:05 +00002331inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
Yong Lic45f0082019-10-10 14:19:01 +08002332{
2333 if (rfAction == "None")
2334 {
2335 return "xyz.openbmc_project.State.Watchdog.Action.None";
2336 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002337 if (rfAction == "PowerCycle")
Yong Lic45f0082019-10-10 14:19:01 +08002338 {
2339 return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
2340 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002341 if (rfAction == "PowerDown")
Yong Lic45f0082019-10-10 14:19:01 +08002342 {
2343 return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
2344 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002345 if (rfAction == "ResetSystem")
Yong Lic45f0082019-10-10 14:19:01 +08002346 {
2347 return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
2348 }
2349
2350 return "";
2351}
2352
2353/**
Yong Li51709ff2019-09-30 14:13:04 +08002354 * @brief Retrieves host watchdog timer properties over DBUS
2355 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002356 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Yong Li51709ff2019-09-30 14:13:04 +08002357 *
2358 * @return None.
2359 */
zhanghch058d1b46d2021-04-01 11:18:24 +08002360inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07002361 getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Yong Li51709ff2019-09-30 14:13:04 +08002362{
2363 BMCWEB_LOG_DEBUG << "Get host watchodg";
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002364 sdbusplus::asio::getAllProperties(
2365 *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
2366 "/xyz/openbmc_project/watchdog/host0",
2367 "xyz.openbmc_project.State.Watchdog",
Ed Tanousac106bf2023-06-07 09:24:59 -07002368 [asyncResp](const boost::system::error_code& ec,
2369 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002370 if (ec)
2371 {
2372 // watchdog service is stopped
2373 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2374 return;
2375 }
2376
2377 BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop.";
2378
2379 nlohmann::json& hostWatchdogTimer =
Ed Tanousac106bf2023-06-07 09:24:59 -07002380 asyncResp->res.jsonValue["HostWatchdogTimer"];
Ed Tanous002d39b2022-05-31 08:59:27 -07002381
2382 // watchdog service is running/enabled
2383 hostWatchdogTimer["Status"]["State"] = "Enabled";
2384
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002385 const bool* enabled = nullptr;
2386 const std::string* expireAction = nullptr;
2387
2388 const bool success = sdbusplus::unpackPropertiesNoThrow(
2389 dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
2390 "ExpireAction", expireAction);
2391
2392 if (!success)
Ed Tanous002d39b2022-05-31 08:59:27 -07002393 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002394 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002395 return;
Ed Tanous002d39b2022-05-31 08:59:27 -07002396 }
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002397
2398 if (enabled != nullptr)
2399 {
2400 hostWatchdogTimer["FunctionEnabled"] = *enabled;
2401 }
2402
2403 if (expireAction != nullptr)
2404 {
2405 std::string action = dbusToRfWatchdogAction(*expireAction);
2406 if (action.empty())
2407 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002408 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002409 return;
2410 }
2411 hostWatchdogTimer["TimeoutAction"] = action;
2412 }
2413 });
Yong Li51709ff2019-09-30 14:13:04 +08002414}
2415
2416/**
Yong Lic45f0082019-10-10 14:19:01 +08002417 * @brief Sets Host WatchDog Timer properties.
2418 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002419 * @param[in] asyncResp Shared pointer for generating response message.
Yong Lic45f0082019-10-10 14:19:01 +08002420 * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming
2421 * RF request.
2422 * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
2423 *
2424 * @return None.
2425 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002426inline void
2427 setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2428 const std::optional<bool> wdtEnable,
2429 const std::optional<std::string>& wdtTimeOutAction)
Yong Lic45f0082019-10-10 14:19:01 +08002430{
2431 BMCWEB_LOG_DEBUG << "Set host watchdog";
2432
2433 if (wdtTimeOutAction)
2434 {
2435 std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
2436 // check if TimeOut Action is Valid
2437 if (wdtTimeOutActStr.empty())
2438 {
2439 BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: "
2440 << *wdtTimeOutAction;
Ed Tanousac106bf2023-06-07 09:24:59 -07002441 messages::propertyValueNotInList(asyncResp->res, *wdtTimeOutAction,
Yong Lic45f0082019-10-10 14:19:01 +08002442 "TimeoutAction");
2443 return;
2444 }
2445
2446 crow::connections::systemBus->async_method_call(
Ed Tanousac106bf2023-06-07 09:24:59 -07002447 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002448 if (ec)
2449 {
2450 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07002451 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002452 return;
2453 }
Yong Lic45f0082019-10-10 14:19:01 +08002454 },
2455 "xyz.openbmc_project.Watchdog",
2456 "/xyz/openbmc_project/watchdog/host0",
2457 "org.freedesktop.DBus.Properties", "Set",
2458 "xyz.openbmc_project.State.Watchdog", "ExpireAction",
Ed Tanous168e20c2021-12-13 14:39:53 -08002459 dbus::utility::DbusVariantType(wdtTimeOutActStr));
Yong Lic45f0082019-10-10 14:19:01 +08002460 }
2461
2462 if (wdtEnable)
2463 {
2464 crow::connections::systemBus->async_method_call(
Ed Tanousac106bf2023-06-07 09:24:59 -07002465 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002466 if (ec)
2467 {
2468 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07002469 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002470 return;
2471 }
Yong Lic45f0082019-10-10 14:19:01 +08002472 },
2473 "xyz.openbmc_project.Watchdog",
2474 "/xyz/openbmc_project/watchdog/host0",
2475 "org.freedesktop.DBus.Properties", "Set",
2476 "xyz.openbmc_project.State.Watchdog", "Enabled",
Ed Tanous168e20c2021-12-13 14:39:53 -08002477 dbus::utility::DbusVariantType(*wdtEnable));
Yong Lic45f0082019-10-10 14:19:01 +08002478 }
2479}
2480
Chris Cain37bbf982021-09-20 10:53:09 -05002481/**
2482 * @brief Parse the Idle Power Saver properties into json
2483 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002484 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Chris Cain37bbf982021-09-20 10:53:09 -05002485 * @param[in] properties IPS property data from DBus.
2486 *
2487 * @return true if successful
2488 */
Jiaqing Zhao1e5b7c82022-08-15 16:15:52 +08002489inline bool
Ed Tanousac106bf2023-06-07 09:24:59 -07002490 parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Jiaqing Zhao1e5b7c82022-08-15 16:15:52 +08002491 const dbus::utility::DBusPropertiesMap& properties)
Chris Cain37bbf982021-09-20 10:53:09 -05002492{
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002493 const bool* enabled = nullptr;
2494 const uint8_t* enterUtilizationPercent = nullptr;
2495 const uint64_t* enterDwellTime = nullptr;
2496 const uint8_t* exitUtilizationPercent = nullptr;
2497 const uint64_t* exitDwellTime = nullptr;
2498
2499 const bool success = sdbusplus::unpackPropertiesNoThrow(
2500 dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
Chris Cain2661b722023-03-22 08:53:21 -05002501 "EnterUtilizationPercent", enterUtilizationPercent, "EnterDwellTime",
2502 enterDwellTime, "ExitUtilizationPercent", exitUtilizationPercent,
2503 "ExitDwellTime", exitDwellTime);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002504
2505 if (!success)
Chris Cain37bbf982021-09-20 10:53:09 -05002506 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002507 return false;
2508 }
2509
2510 if (enabled != nullptr)
2511 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002512 asyncResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled;
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002513 }
2514
2515 if (enterUtilizationPercent != nullptr)
2516 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002517 asyncResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002518 *enterUtilizationPercent;
2519 }
2520
2521 if (enterDwellTime != nullptr)
2522 {
2523 const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime);
Ed Tanousac106bf2023-06-07 09:24:59 -07002524 asyncResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002525 std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
2526 .count();
2527 }
2528
2529 if (exitUtilizationPercent != nullptr)
2530 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002531 asyncResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002532 *exitUtilizationPercent;
2533 }
2534
2535 if (exitDwellTime != nullptr)
2536 {
2537 const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime);
Ed Tanousac106bf2023-06-07 09:24:59 -07002538 asyncResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002539 std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
2540 .count();
Chris Cain37bbf982021-09-20 10:53:09 -05002541 }
2542
2543 return true;
2544}
2545
2546/**
2547 * @brief Retrieves host watchdog timer properties over DBUS
2548 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002549 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Chris Cain37bbf982021-09-20 10:53:09 -05002550 *
2551 * @return None.
2552 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002553inline void
2554 getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Chris Cain37bbf982021-09-20 10:53:09 -05002555{
2556 BMCWEB_LOG_DEBUG << "Get idle power saver parameters";
2557
2558 // Get IdlePowerSaver object path:
George Liue99073f2022-12-09 11:06:16 +08002559 constexpr std::array<std::string_view, 1> interfaces = {
2560 "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2561 dbus::utility::getSubTree(
2562 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002563 [asyncResp](const boost::system::error_code& ec,
2564 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002565 if (ec)
2566 {
2567 BMCWEB_LOG_DEBUG
2568 << "DBUS response error on Power.IdlePowerSaver GetSubTree "
2569 << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07002570 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002571 return;
2572 }
2573 if (subtree.empty())
2574 {
2575 // This is an optional interface so just return
2576 // if there is no instance found
2577 BMCWEB_LOG_DEBUG << "No instances found";
2578 return;
2579 }
2580 if (subtree.size() > 1)
2581 {
2582 // More then one PowerIdlePowerSaver object is not supported and
2583 // is an error
2584 BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus "
2585 "Power.IdlePowerSaver objects: "
2586 << subtree.size();
Ed Tanousac106bf2023-06-07 09:24:59 -07002587 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002588 return;
2589 }
2590 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2591 {
2592 BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07002593 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002594 return;
2595 }
2596 const std::string& path = subtree[0].first;
2597 const std::string& service = subtree[0].second.begin()->first;
2598 if (service.empty())
2599 {
2600 BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07002601 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002602 return;
2603 }
2604
2605 // Valid IdlePowerSaver object found, now read the current values
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002606 sdbusplus::asio::getAllProperties(
2607 *crow::connections::systemBus, service, path,
2608 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
Ed Tanousac106bf2023-06-07 09:24:59 -07002609 [asyncResp](const boost::system::error_code& ec2,
2610 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous8a592812022-06-04 09:06:59 -07002611 if (ec2)
Chris Cain37bbf982021-09-20 10:53:09 -05002612 {
Ed Tanous002d39b2022-05-31 08:59:27 -07002613 BMCWEB_LOG_ERROR
Ed Tanous8a592812022-06-04 09:06:59 -07002614 << "DBUS response error on IdlePowerSaver GetAll: " << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -07002615 messages::internalError(asyncResp->res);
Chris Cain37bbf982021-09-20 10:53:09 -05002616 return;
2617 }
2618
Ed Tanousac106bf2023-06-07 09:24:59 -07002619 if (!parseIpsProperties(asyncResp, properties))
Ed Tanous002d39b2022-05-31 08:59:27 -07002620 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002621 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002622 return;
2623 }
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002624 });
George Liue99073f2022-12-09 11:06:16 +08002625 });
Chris Cain37bbf982021-09-20 10:53:09 -05002626
2627 BMCWEB_LOG_DEBUG << "EXIT: Get idle power saver parameters";
2628}
2629
2630/**
2631 * @brief Sets Idle Power Saver properties.
2632 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002633 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain37bbf982021-09-20 10:53:09 -05002634 * @param[in] ipsEnable The IPS Enable value (true/false) from incoming
2635 * RF request.
2636 * @param[in] ipsEnterUtil The utilization limit to enter idle state.
2637 * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil
2638 * before entering idle state.
2639 * @param[in] ipsExitUtil The utilization limit when exiting idle state.
2640 * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil
2641 * before exiting idle state
2642 *
2643 * @return None.
2644 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002645inline void
2646 setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2647 const std::optional<bool> ipsEnable,
2648 const std::optional<uint8_t> ipsEnterUtil,
2649 const std::optional<uint64_t> ipsEnterTime,
2650 const std::optional<uint8_t> ipsExitUtil,
2651 const std::optional<uint64_t> ipsExitTime)
Chris Cain37bbf982021-09-20 10:53:09 -05002652{
2653 BMCWEB_LOG_DEBUG << "Set idle power saver properties";
2654
2655 // Get IdlePowerSaver object path:
George Liue99073f2022-12-09 11:06:16 +08002656 constexpr std::array<std::string_view, 1> interfaces = {
2657 "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2658 dbus::utility::getSubTree(
2659 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002660 [asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil,
George Liue99073f2022-12-09 11:06:16 +08002661 ipsExitTime](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08002662 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002663 if (ec)
2664 {
2665 BMCWEB_LOG_DEBUG
2666 << "DBUS response error on Power.IdlePowerSaver GetSubTree "
2667 << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07002668 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002669 return;
2670 }
2671 if (subtree.empty())
2672 {
2673 // This is an optional D-Bus object, but user attempted to patch
Ed Tanousac106bf2023-06-07 09:24:59 -07002674 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
Ed Tanous002d39b2022-05-31 08:59:27 -07002675 "IdlePowerSaver");
2676 return;
2677 }
2678 if (subtree.size() > 1)
2679 {
2680 // More then one PowerIdlePowerSaver object is not supported and
2681 // is an error
2682 BMCWEB_LOG_DEBUG
2683 << "Found more than 1 system D-Bus Power.IdlePowerSaver objects: "
2684 << subtree.size();
Ed Tanousac106bf2023-06-07 09:24:59 -07002685 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002686 return;
2687 }
2688 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2689 {
2690 BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07002691 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002692 return;
2693 }
2694 const std::string& path = subtree[0].first;
2695 const std::string& service = subtree[0].second.begin()->first;
2696 if (service.empty())
2697 {
2698 BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07002699 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002700 return;
2701 }
Chris Cain37bbf982021-09-20 10:53:09 -05002702
Ed Tanous002d39b2022-05-31 08:59:27 -07002703 // Valid Power IdlePowerSaver object found, now set any values that
2704 // need to be updated
Chris Cain37bbf982021-09-20 10:53:09 -05002705
Ed Tanous002d39b2022-05-31 08:59:27 -07002706 if (ipsEnable)
2707 {
2708 crow::connections::systemBus->async_method_call(
Ed Tanousac106bf2023-06-07 09:24:59 -07002709 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002710 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002711 {
Ed Tanous8a592812022-06-04 09:06:59 -07002712 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -07002713 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002714 return;
2715 }
2716 },
2717 service, path, "org.freedesktop.DBus.Properties", "Set",
2718 "xyz.openbmc_project.Control.Power.IdlePowerSaver", "Enabled",
2719 dbus::utility::DbusVariantType(*ipsEnable));
2720 }
2721 if (ipsEnterUtil)
2722 {
2723 crow::connections::systemBus->async_method_call(
Ed Tanousac106bf2023-06-07 09:24:59 -07002724 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002725 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002726 {
Ed Tanous8a592812022-06-04 09:06:59 -07002727 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -07002728 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002729 return;
2730 }
2731 },
2732 service, path, "org.freedesktop.DBus.Properties", "Set",
2733 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2734 "EnterUtilizationPercent",
2735 dbus::utility::DbusVariantType(*ipsEnterUtil));
2736 }
2737 if (ipsEnterTime)
2738 {
2739 // Convert from seconds into milliseconds for DBus
2740 const uint64_t timeMilliseconds = *ipsEnterTime * 1000;
2741 crow::connections::systemBus->async_method_call(
Ed Tanousac106bf2023-06-07 09:24:59 -07002742 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002743 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002744 {
Ed Tanous8a592812022-06-04 09:06:59 -07002745 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -07002746 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002747 return;
2748 }
2749 },
2750 service, path, "org.freedesktop.DBus.Properties", "Set",
2751 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2752 "EnterDwellTime",
2753 dbus::utility::DbusVariantType(timeMilliseconds));
2754 }
2755 if (ipsExitUtil)
2756 {
2757 crow::connections::systemBus->async_method_call(
Ed Tanousac106bf2023-06-07 09:24:59 -07002758 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002759 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002760 {
Ed Tanous8a592812022-06-04 09:06:59 -07002761 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -07002762 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002763 return;
2764 }
2765 },
2766 service, path, "org.freedesktop.DBus.Properties", "Set",
2767 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2768 "ExitUtilizationPercent",
2769 dbus::utility::DbusVariantType(*ipsExitUtil));
2770 }
2771 if (ipsExitTime)
2772 {
2773 // Convert from seconds into milliseconds for DBus
2774 const uint64_t timeMilliseconds = *ipsExitTime * 1000;
2775 crow::connections::systemBus->async_method_call(
Ed Tanousac106bf2023-06-07 09:24:59 -07002776 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002777 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002778 {
Ed Tanous8a592812022-06-04 09:06:59 -07002779 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -07002780 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002781 return;
2782 }
2783 },
2784 service, path, "org.freedesktop.DBus.Properties", "Set",
2785 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2786 "ExitDwellTime",
2787 dbus::utility::DbusVariantType(timeMilliseconds));
2788 }
George Liue99073f2022-12-09 11:06:16 +08002789 });
Chris Cain37bbf982021-09-20 10:53:09 -05002790
2791 BMCWEB_LOG_DEBUG << "EXIT: Set idle power saver parameters";
2792}
2793
Ed Tanousdd60b9e2022-07-07 17:03:54 -07002794inline void handleComputerSystemHead(
2795 crow::App& app, const crow::Request& req,
2796 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2797{
2798 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2799 {
2800 return;
2801 }
2802 asyncResp->res.addHeader(
2803 boost::beast::http::field::link,
2804 "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby");
2805}
2806
Yong Lic45f0082019-10-10 14:19:01 +08002807/**
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002808 * SystemsCollection derived class for delivering ComputerSystems Collection
2809 * Schema
2810 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002811inline void requestRoutesSystemsCollection(App& app)
Ed Tanous1abe55e2018-09-05 08:30:59 -07002812{
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002813 BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
Ed Tanousdd60b9e2022-07-07 17:03:54 -07002814 .privileges(redfish::privileges::headComputerSystemCollection)
2815 .methods(boost::beast::http::verb::head)(
2816 std::bind_front(handleComputerSystemHead, std::ref(app)));
2817
2818 BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
Ed Tanoused398212021-06-09 17:05:54 -07002819 .privileges(redfish::privileges::getComputerSystemCollection)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002820 .methods(boost::beast::http::verb::get)(
Ed Tanousf4c99e72021-10-04 17:02:43 -07002821 [&app](const crow::Request& req,
2822 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
Carson Labrado3ba00072022-06-06 19:40:56 +00002823 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -07002824 {
2825 return;
2826 }
Ed Tanousdd60b9e2022-07-07 17:03:54 -07002827
2828 asyncResp->res.addHeader(
2829 boost::beast::http::field::link,
2830 "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby");
Ed Tanous002d39b2022-05-31 08:59:27 -07002831 asyncResp->res.jsonValue["@odata.type"] =
2832 "#ComputerSystemCollection.ComputerSystemCollection";
2833 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
2834 asyncResp->res.jsonValue["Name"] = "Computer System Collection";
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002835
Ed Tanous7f3e84a2022-12-28 16:22:54 -08002836 nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"];
2837 ifaceArray = nlohmann::json::array();
2838 if constexpr (bmcwebEnableMultiHost)
2839 {
2840 asyncResp->res.jsonValue["Members@odata.count"] = 0;
2841 // Option currently returns no systems. TBD
2842 return;
2843 }
2844 asyncResp->res.jsonValue["Members@odata.count"] = 1;
2845 nlohmann::json::object_t system;
2846 system["@odata.id"] = "/redfish/v1/Systems/system";
2847 ifaceArray.emplace_back(std::move(system));
Ed Tanous002d39b2022-05-31 08:59:27 -07002848 sdbusplus::asio::getProperty<std::string>(
2849 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
2850 "/xyz/openbmc_project/network/hypervisor",
2851 "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08002852 [asyncResp](const boost::system::error_code& ec2,
Ed Tanous002d39b2022-05-31 08:59:27 -07002853 const std::string& /*hostName*/) {
Ed Tanous7f3e84a2022-12-28 16:22:54 -08002854 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002855 {
Ed Tanous7f3e84a2022-12-28 16:22:54 -08002856 return;
Ed Tanous002d39b2022-05-31 08:59:27 -07002857 }
Ed Tanous7f3e84a2022-12-28 16:22:54 -08002858 auto val = asyncResp->res.jsonValue.find("Members@odata.count");
2859 if (val == asyncResp->res.jsonValue.end())
2860 {
2861 BMCWEB_LOG_CRITICAL << "Count wasn't found??";
2862 return;
2863 }
2864 uint64_t* count = val->get_ptr<uint64_t*>();
2865 if (count == nullptr)
2866 {
2867 BMCWEB_LOG_CRITICAL << "Count wasn't found??";
2868 return;
2869 }
2870 *count = *count + 1;
2871 BMCWEB_LOG_DEBUG << "Hypervisor is available";
2872 nlohmann::json& ifaceArray2 = asyncResp->res.jsonValue["Members"];
2873 nlohmann::json::object_t hypervisor;
2874 hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor";
2875 ifaceArray2.emplace_back(std::move(hypervisor));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002876 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002877 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002878}
Sunitha Harish462023a2020-02-19 08:34:59 -06002879
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002880/**
2881 * Function transceives data with dbus directly.
2882 */
Ed Tanous4f48d5f2021-06-21 08:27:45 -07002883inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002884{
Patrick Williams89492a12023-05-10 07:51:34 -05002885 constexpr const char* serviceName = "xyz.openbmc_project.Control.Host.NMI";
2886 constexpr const char* objectPath = "/xyz/openbmc_project/control/host0/nmi";
2887 constexpr const char* interfaceName =
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002888 "xyz.openbmc_project.Control.Host.NMI";
Patrick Williams89492a12023-05-10 07:51:34 -05002889 constexpr const char* method = "NMI";
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002890
2891 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08002892 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002893 if (ec)
2894 {
2895 BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
2896 messages::internalError(asyncResp->res);
2897 return;
2898 }
2899 messages::success(asyncResp->res);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002900 },
2901 serviceName, objectPath, interfaceName, method);
2902}
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002903
2904/**
Andrew Geisslerfc903b32023-05-31 14:15:42 -04002905 * Handle error responses from d-bus for system power requests
2906 */
2907inline void handleSystemActionResetError(const boost::system::error_code& ec,
2908 const sdbusplus::message_t& eMsg,
2909 std::string_view resetType,
2910 crow::Response& res)
2911{
2912 if (ec.value() == boost::asio::error::invalid_argument)
2913 {
2914 messages::actionParameterNotSupported(res, resetType, "Reset");
2915 return;
2916 }
2917
2918 if (eMsg.get_error() == nullptr)
2919 {
2920 BMCWEB_LOG_ERROR << "D-Bus response error: " << ec;
2921 messages::internalError(res);
2922 return;
2923 }
2924 std::string_view errorMessage = eMsg.get_error()->name;
2925
2926 // If operation failed due to BMC not being in Ready state, tell
2927 // user to retry in a bit
2928 if ((errorMessage ==
2929 std::string_view(
2930 "xyz.openbmc_project.State.Chassis.Error.BMCNotReady")) ||
2931 (errorMessage ==
2932 std::string_view("xyz.openbmc_project.State.Host.Error.BMCNotReady")))
2933 {
2934 BMCWEB_LOG_DEBUG << "BMC not ready, operation not allowed right now";
2935 messages::serviceTemporarilyUnavailable(res, "10");
2936 return;
2937 }
2938
2939 BMCWEB_LOG_ERROR << "System Action Reset transition fail " << ec
2940 << " sdbusplus:" << errorMessage;
2941 messages::internalError(res);
2942}
2943
2944/**
Ed Tanouscc340dd2018-08-29 13:43:38 -07002945 * SystemActionsReset class supports handle POST method for Reset action.
2946 * The class retrieves and sends data directly to D-Bus.
2947 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002948inline void requestRoutesSystemActionsReset(App& app)
Ed Tanouscc340dd2018-08-29 13:43:38 -07002949{
Ed Tanouscc340dd2018-08-29 13:43:38 -07002950 /**
2951 * Function handles POST method request.
2952 * Analyzes POST body message before sends Reset request data to D-Bus.
2953 */
Ed Tanous7f3e84a2022-12-28 16:22:54 -08002954 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/")
Ed Tanoused398212021-06-09 17:05:54 -07002955 .privileges(redfish::privileges::postComputerSystem)
Ed Tanous002d39b2022-05-31 08:59:27 -07002956 .methods(boost::beast::http::verb::post)(
2957 [&app](const crow::Request& req,
Ed Tanous7f3e84a2022-12-28 16:22:54 -08002958 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2959 const std::string& systemId) {
Carson Labrado3ba00072022-06-06 19:40:56 +00002960 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -07002961 {
2962 return;
2963 }
Ed Tanous7f3e84a2022-12-28 16:22:54 -08002964 if constexpr (bmcwebEnableMultiHost)
2965 {
2966 // Option currently returns no systems. TBD
2967 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2968 systemId);
2969 return;
2970 }
2971 if (systemId != "system")
2972 {
2973 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2974 systemId);
2975 return;
2976 }
Ed Tanous002d39b2022-05-31 08:59:27 -07002977 std::string resetType;
2978 if (!json_util::readJsonAction(req, asyncResp->res, "ResetType",
2979 resetType))
2980 {
2981 return;
2982 }
Ed Tanous9712f8a2018-09-21 13:38:49 -07002983
Ed Tanous002d39b2022-05-31 08:59:27 -07002984 // Get the command and host vs. chassis
2985 std::string command;
2986 bool hostCommand = true;
2987 if ((resetType == "On") || (resetType == "ForceOn"))
2988 {
2989 command = "xyz.openbmc_project.State.Host.Transition.On";
2990 hostCommand = true;
2991 }
2992 else if (resetType == "ForceOff")
2993 {
2994 command = "xyz.openbmc_project.State.Chassis.Transition.Off";
2995 hostCommand = false;
2996 }
2997 else if (resetType == "ForceRestart")
2998 {
2999 command =
3000 "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
3001 hostCommand = true;
3002 }
3003 else if (resetType == "GracefulShutdown")
3004 {
3005 command = "xyz.openbmc_project.State.Host.Transition.Off";
3006 hostCommand = true;
3007 }
3008 else if (resetType == "GracefulRestart")
3009 {
3010 command =
3011 "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
3012 hostCommand = true;
3013 }
3014 else if (resetType == "PowerCycle")
3015 {
3016 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
3017 hostCommand = true;
3018 }
3019 else if (resetType == "Nmi")
3020 {
3021 doNMI(asyncResp);
3022 return;
3023 }
3024 else
3025 {
3026 messages::actionParameterUnknown(asyncResp->res, "Reset",
3027 resetType);
3028 return;
3029 }
Ed Tanouscc340dd2018-08-29 13:43:38 -07003030
Ed Tanous002d39b2022-05-31 08:59:27 -07003031 if (hostCommand)
3032 {
3033 crow::connections::systemBus->async_method_call(
Andrew Geisslerfc903b32023-05-31 14:15:42 -04003034 [asyncResp, resetType](const boost::system::error_code& ec,
3035 sdbusplus::message_t& sdbusErrMsg) {
Ed Tanous002d39b2022-05-31 08:59:27 -07003036 if (ec)
3037 {
Andrew Geisslerfc903b32023-05-31 14:15:42 -04003038 handleSystemActionResetError(ec, sdbusErrMsg, resetType,
3039 asyncResp->res);
3040
Ed Tanous002d39b2022-05-31 08:59:27 -07003041 return;
3042 }
3043 messages::success(asyncResp->res);
3044 },
3045 "xyz.openbmc_project.State.Host",
3046 "/xyz/openbmc_project/state/host0",
3047 "org.freedesktop.DBus.Properties", "Set",
3048 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
3049 dbus::utility::DbusVariantType{command});
3050 }
3051 else
3052 {
3053 crow::connections::systemBus->async_method_call(
Andrew Geisslerfc903b32023-05-31 14:15:42 -04003054 [asyncResp, resetType](const boost::system::error_code& ec,
3055 sdbusplus::message_t& sdbusErrMsg) {
Ed Tanous002d39b2022-05-31 08:59:27 -07003056 if (ec)
3057 {
Andrew Geisslerfc903b32023-05-31 14:15:42 -04003058 handleSystemActionResetError(ec, sdbusErrMsg, resetType,
3059 asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07003060 return;
3061 }
3062 messages::success(asyncResp->res);
3063 },
3064 "xyz.openbmc_project.State.Chassis",
3065 "/xyz/openbmc_project/state/chassis0",
3066 "org.freedesktop.DBus.Properties", "Set",
3067 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
3068 dbus::utility::DbusVariantType{command});
3069 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003070 });
3071}
Ed Tanouscc340dd2018-08-29 13:43:38 -07003072
Ed Tanous38c8a6f2022-09-01 16:37:27 -07003073inline void handleComputerSystemCollectionHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003074 App& app, const crow::Request& req,
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003075 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3076 const std::string& /*systemName*/)
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003077{
3078 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3079 {
3080 return;
3081 }
3082
3083 asyncResp->res.addHeader(
3084 boost::beast::http::field::link,
3085 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3086}
3087
Abhishek Patel5c3e9272021-06-24 10:11:33 -05003088inline void afterPortRequest(
3089 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3090 const boost::system::error_code& ec,
3091 const std::vector<std::tuple<std::string, std::string, bool>>& socketData)
3092{
3093 if (ec)
3094 {
3095 messages::internalError(asyncResp->res);
3096 return;
3097 }
3098 for (const auto& data : socketData)
3099 {
3100 const std::string& socketPath = get<0>(data);
3101 const std::string& protocolName = get<1>(data);
3102 bool isProtocolEnabled = get<2>(data);
3103 nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"];
3104 dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled;
3105 // need to retrieve port number for
3106 // obmc-console-ssh service
3107 if (protocolName == "SSH")
3108 {
3109 getPortNumber(socketPath, [asyncResp, protocolName](
Ed Tanous81c4e332023-05-18 10:30:34 -07003110 const boost::system::error_code& ec1,
Abhishek Patel5c3e9272021-06-24 10:11:33 -05003111 int portNumber) {
3112 if (ec1)
3113 {
3114 messages::internalError(asyncResp->res);
3115 return;
3116 }
3117 nlohmann::json& dataJson1 =
3118 asyncResp->res.jsonValue["SerialConsole"];
3119 dataJson1[protocolName]["Port"] = portNumber;
3120 });
3121 }
3122 }
3123}
Ed Tanouscc340dd2018-08-29 13:43:38 -07003124/**
Ed Tanous66173382018-08-15 18:20:59 -07003125 * Systems derived class for delivering Computer Systems Schema.
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02003126 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003127inline void requestRoutesSystems(App& app)
Ed Tanous1abe55e2018-09-05 08:30:59 -07003128{
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003129 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003130 .privileges(redfish::privileges::headComputerSystem)
3131 .methods(boost::beast::http::verb::head)(
3132 std::bind_front(handleComputerSystemCollectionHead, std::ref(app)));
Ed Tanous1abe55e2018-09-05 08:30:59 -07003133 /**
3134 * Functions triggers appropriate requests on DBus
3135 */
Ed Tanous22d268c2022-05-19 09:39:07 -07003136 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07003137 .privileges(redfish::privileges::getComputerSystem)
Ed Tanous002d39b2022-05-31 08:59:27 -07003138 .methods(boost::beast::http::verb::get)(
3139 [&app](const crow::Request& req,
Ed Tanous22d268c2022-05-19 09:39:07 -07003140 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3141 const std::string& systemName) {
Carson Labrado3ba00072022-06-06 19:40:56 +00003142 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -07003143 {
3144 return;
3145 }
Asmitha Karunanithi746b56f2023-02-27 23:29:49 -06003146
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003147 if constexpr (bmcwebEnableMultiHost)
3148 {
3149 // Option currently returns no systems. TBD
3150 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3151 systemName);
3152 return;
3153 }
3154
Asmitha Karunanithi746b56f2023-02-27 23:29:49 -06003155 if (systemName == "hypervisor")
3156 {
3157 handleHypervisorSystemGet(asyncResp);
3158 return;
3159 }
3160
Ed Tanous22d268c2022-05-19 09:39:07 -07003161 if (systemName != "system")
3162 {
3163 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3164 systemName);
3165 return;
3166 }
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003167 asyncResp->res.addHeader(
3168 boost::beast::http::field::link,
3169 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
Ed Tanous002d39b2022-05-31 08:59:27 -07003170 asyncResp->res.jsonValue["@odata.type"] =
3171 "#ComputerSystem.v1_16_0.ComputerSystem";
3172 asyncResp->res.jsonValue["Name"] = "system";
3173 asyncResp->res.jsonValue["Id"] = "system";
3174 asyncResp->res.jsonValue["SystemType"] = "Physical";
3175 asyncResp->res.jsonValue["Description"] = "Computer System";
3176 asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -05003177 if constexpr (bmcwebEnableProcMemStatus)
3178 {
3179 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
3180 "Disabled";
3181 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
3182 "Disabled";
3183 }
Ninad Palsulecf0e0042023-05-18 17:18:09 -05003184 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
3185 uint64_t(0);
Ed Tanous002d39b2022-05-31 08:59:27 -07003186 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
Ed Tanous04a258f2018-10-15 08:00:41 -07003187
Ed Tanous002d39b2022-05-31 08:59:27 -07003188 asyncResp->res.jsonValue["Processors"]["@odata.id"] =
3189 "/redfish/v1/Systems/system/Processors";
3190 asyncResp->res.jsonValue["Memory"]["@odata.id"] =
3191 "/redfish/v1/Systems/system/Memory";
3192 asyncResp->res.jsonValue["Storage"]["@odata.id"] =
3193 "/redfish/v1/Systems/system/Storage";
Sunny Srivastava31791052021-03-12 10:39:16 -06003194 asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] =
3195 "/redfish/v1/Systems/system/FabricAdapters";
Ed Tanous029573d2019-02-01 10:57:49 -08003196
Ed Tanous002d39b2022-05-31 08:59:27 -07003197 asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] =
3198 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset";
3199 asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]
3200 ["@Redfish.ActionInfo"] =
3201 "/redfish/v1/Systems/system/ResetActionInfo";
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02003202
Ed Tanous002d39b2022-05-31 08:59:27 -07003203 asyncResp->res.jsonValue["LogServices"]["@odata.id"] =
3204 "/redfish/v1/Systems/system/LogServices";
3205 asyncResp->res.jsonValue["Bios"]["@odata.id"] =
3206 "/redfish/v1/Systems/system/Bios";
Jason M. Billsc4bf6372018-11-05 13:48:27 -08003207
Ed Tanous002d39b2022-05-31 08:59:27 -07003208 nlohmann::json::array_t managedBy;
3209 nlohmann::json& manager = managedBy.emplace_back();
3210 manager["@odata.id"] = "/redfish/v1/Managers/bmc";
3211 asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy);
3212 asyncResp->res.jsonValue["Status"]["Health"] = "OK";
3213 asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06003214
Ed Tanous002d39b2022-05-31 08:59:27 -07003215 // Fill in SerialConsole info
3216 asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15;
3217 asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] =
3218 true;
Ed Tanous14766872022-03-15 10:44:42 -07003219
Ed Tanous002d39b2022-05-31 08:59:27 -07003220 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] =
3221 true;
3222 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200;
3223 asyncResp->res
3224 .jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] =
3225 "Press ~. to exit console";
Abhishek Patel5c3e9272021-06-24 10:11:33 -05003226 getPortStatusAndPath(std::span{protocolToDBusForSystems},
3227 std::bind_front(afterPortRequest, asyncResp));
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06003228
3229#ifdef BMCWEB_ENABLE_KVM
Ed Tanous002d39b2022-05-31 08:59:27 -07003230 // Fill in GraphicalConsole info
3231 asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true;
3232 asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] =
3233 4;
Ed Tanous613dabe2022-07-09 11:17:36 -07003234 asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] =
3235 nlohmann::json::array_t({"KVMIP"});
Ed Tanous14766872022-03-15 10:44:42 -07003236
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06003237#endif // BMCWEB_ENABLE_KVM
James Feistb49ac872019-05-21 15:12:01 -07003238
Ed Tanous002d39b2022-05-31 08:59:27 -07003239 auto health = std::make_shared<HealthPopulate>(asyncResp);
Willy Tu13451e32023-05-24 16:08:18 -07003240 if constexpr (bmcwebEnableHealthPopulate)
3241 {
3242 constexpr std::array<std::string_view, 4> inventoryForSystems{
3243 "xyz.openbmc_project.Inventory.Item.Dimm",
3244 "xyz.openbmc_project.Inventory.Item.Cpu",
3245 "xyz.openbmc_project.Inventory.Item.Drive",
3246 "xyz.openbmc_project.Inventory.Item.StorageController"};
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003247
Willy Tu13451e32023-05-24 16:08:18 -07003248 dbus::utility::getSubTreePaths(
3249 "/", 0, inventoryForSystems,
3250 [health](const boost::system::error_code& ec,
3251 const std::vector<std::string>& resp) {
3252 if (ec)
3253 {
3254 // no inventory
3255 return;
3256 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003257
Willy Tu13451e32023-05-24 16:08:18 -07003258 health->inventory = resp;
3259 });
3260 health->populate();
3261 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003262
Ed Tanous002d39b2022-05-31 08:59:27 -07003263 getMainChassisId(asyncResp,
3264 [](const std::string& chassisId,
3265 const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
3266 nlohmann::json::array_t chassisArray;
3267 nlohmann::json& chassis = chassisArray.emplace_back();
Ed Tanousef4c65b2023-04-24 15:28:50 -07003268 chassis["@odata.id"] = boost::urls::format("/redfish/v1/Chassis/{}",
3269 chassisId);
Ed Tanous002d39b2022-05-31 08:59:27 -07003270 aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray);
3271 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003272
Ed Tanous002d39b2022-05-31 08:59:27 -07003273 getLocationIndicatorActive(asyncResp);
3274 // TODO (Gunnar): Remove IndicatorLED after enough time has passed
3275 getIndicatorLedState(asyncResp);
3276 getComputerSystem(asyncResp, health);
3277 getHostState(asyncResp);
3278 getBootProperties(asyncResp);
3279 getBootProgress(asyncResp);
Hieu Huynhb6d5d452022-10-07 09:41:46 +00003280 getBootProgressLastStateTime(asyncResp);
Lakshmi Yadlapati472bd202023-03-22 09:57:05 -05003281 pcie_util::getPCIeDeviceList(asyncResp, "PCIeDevices");
Ed Tanous002d39b2022-05-31 08:59:27 -07003282 getHostWatchdogTimer(asyncResp);
3283 getPowerRestorePolicy(asyncResp);
Corey Hardesty797d5da2022-04-26 17:54:52 +08003284 getAutomaticRetryPolicy(asyncResp);
Ed Tanous002d39b2022-05-31 08:59:27 -07003285 getLastResetTime(asyncResp);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003286#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
Ed Tanous002d39b2022-05-31 08:59:27 -07003287 getProvisioningStatus(asyncResp);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003288#endif
Ed Tanous002d39b2022-05-31 08:59:27 -07003289 getTrustedModuleRequiredToBoot(asyncResp);
3290 getPowerMode(asyncResp);
3291 getIdlePowerSaver(asyncResp);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003292 });
Jiaqing Zhao550a6bf2022-04-26 17:54:52 +08003293
Ed Tanous22d268c2022-05-19 09:39:07 -07003294 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07003295 .privileges(redfish::privileges::patchComputerSystem)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003296 .methods(boost::beast::http::verb::patch)(
Ed Tanous45ca1b82022-03-25 13:07:27 -07003297 [&app](const crow::Request& req,
Ed Tanous22d268c2022-05-19 09:39:07 -07003298 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3299 const std::string& systemName) {
Carson Labrado3ba00072022-06-06 19:40:56 +00003300 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -07003301 {
3302 return;
3303 }
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003304 if constexpr (bmcwebEnableMultiHost)
3305 {
3306 // Option currently returns no systems. TBD
3307 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3308 systemName);
3309 return;
3310 }
Ed Tanous22d268c2022-05-19 09:39:07 -07003311 if (systemName != "system")
3312 {
3313 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3314 systemName);
3315 return;
3316 }
3317
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003318 asyncResp->res.addHeader(
3319 boost::beast::http::field::link,
3320 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3321
Ed Tanous002d39b2022-05-31 08:59:27 -07003322 std::optional<bool> locationIndicatorActive;
3323 std::optional<std::string> indicatorLed;
3324 std::optional<std::string> assetTag;
3325 std::optional<std::string> powerRestorePolicy;
3326 std::optional<std::string> powerMode;
3327 std::optional<bool> wdtEnable;
3328 std::optional<std::string> wdtTimeOutAction;
3329 std::optional<std::string> bootSource;
3330 std::optional<std::string> bootType;
3331 std::optional<std::string> bootEnable;
3332 std::optional<std::string> bootAutomaticRetry;
Corey Hardesty797d5da2022-04-26 17:54:52 +08003333 std::optional<uint32_t> bootAutomaticRetryAttempts;
Ed Tanous002d39b2022-05-31 08:59:27 -07003334 std::optional<bool> bootTrustedModuleRequired;
3335 std::optional<bool> ipsEnable;
3336 std::optional<uint8_t> ipsEnterUtil;
3337 std::optional<uint64_t> ipsEnterTime;
3338 std::optional<uint8_t> ipsExitUtil;
3339 std::optional<uint64_t> ipsExitTime;
Jiaqing Zhao550a6bf2022-04-26 17:54:52 +08003340
Ed Tanous002d39b2022-05-31 08:59:27 -07003341 // clang-format off
Ed Tanous22d268c2022-05-19 09:39:07 -07003342 if (!json_util::readJsonPatch(
3343 req, asyncResp->res,
3344 "IndicatorLED", indicatorLed,
3345 "LocationIndicatorActive", locationIndicatorActive,
3346 "AssetTag", assetTag,
3347 "PowerRestorePolicy", powerRestorePolicy,
3348 "PowerMode", powerMode,
3349 "HostWatchdogTimer/FunctionEnabled", wdtEnable,
3350 "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction,
3351 "Boot/BootSourceOverrideTarget", bootSource,
3352 "Boot/BootSourceOverrideMode", bootType,
3353 "Boot/BootSourceOverrideEnabled", bootEnable,
3354 "Boot/AutomaticRetryConfig", bootAutomaticRetry,
Corey Hardesty797d5da2022-04-26 17:54:52 +08003355 "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts,
Ed Tanous22d268c2022-05-19 09:39:07 -07003356 "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired,
3357 "IdlePowerSaver/Enabled", ipsEnable,
3358 "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil,
3359 "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime,
3360 "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil,
3361 "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime))
3362 {
3363 return;
3364 }
Ed Tanous002d39b2022-05-31 08:59:27 -07003365 // clang-format on
James Feistb49ac872019-05-21 15:12:01 -07003366
Ed Tanous002d39b2022-05-31 08:59:27 -07003367 asyncResp->res.result(boost::beast::http::status::no_content);
James Feistb49ac872019-05-21 15:12:01 -07003368
Ed Tanous002d39b2022-05-31 08:59:27 -07003369 if (assetTag)
3370 {
3371 setAssetTag(asyncResp, *assetTag);
3372 }
James Feistb49ac872019-05-21 15:12:01 -07003373
Ed Tanous002d39b2022-05-31 08:59:27 -07003374 if (wdtEnable || wdtTimeOutAction)
3375 {
3376 setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
3377 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003378
Ed Tanous002d39b2022-05-31 08:59:27 -07003379 if (bootSource || bootType || bootEnable)
3380 {
3381 setBootProperties(asyncResp, bootSource, bootType, bootEnable);
3382 }
3383 if (bootAutomaticRetry)
3384 {
3385 setAutomaticRetry(asyncResp, *bootAutomaticRetry);
3386 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003387
Corey Hardesty797d5da2022-04-26 17:54:52 +08003388 if (bootAutomaticRetryAttempts)
3389 {
3390 setAutomaticRetryAttempts(asyncResp,
3391 bootAutomaticRetryAttempts.value());
3392 }
3393
Ed Tanous002d39b2022-05-31 08:59:27 -07003394 if (bootTrustedModuleRequired)
3395 {
3396 setTrustedModuleRequiredToBoot(asyncResp,
3397 *bootTrustedModuleRequired);
3398 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003399
Ed Tanous002d39b2022-05-31 08:59:27 -07003400 if (locationIndicatorActive)
3401 {
3402 setLocationIndicatorActive(asyncResp, *locationIndicatorActive);
3403 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003404
Ed Tanous002d39b2022-05-31 08:59:27 -07003405 // TODO (Gunnar): Remove IndicatorLED after enough time has
3406 // passed
3407 if (indicatorLed)
3408 {
3409 setIndicatorLedState(asyncResp, *indicatorLed);
3410 asyncResp->res.addHeader(boost::beast::http::field::warning,
3411 "299 - \"IndicatorLED is deprecated. Use "
3412 "LocationIndicatorActive instead.\"");
3413 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003414
Ed Tanous002d39b2022-05-31 08:59:27 -07003415 if (powerRestorePolicy)
3416 {
3417 setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
3418 }
Chris Cain3a2d04242021-05-28 16:57:10 -05003419
Ed Tanous002d39b2022-05-31 08:59:27 -07003420 if (powerMode)
3421 {
3422 setPowerMode(asyncResp, *powerMode);
3423 }
Chris Cain37bbf982021-09-20 10:53:09 -05003424
Ed Tanous002d39b2022-05-31 08:59:27 -07003425 if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil ||
3426 ipsExitTime)
3427 {
3428 setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime,
3429 ipsExitUtil, ipsExitTime);
3430 }
3431 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003432}
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303433
Ed Tanous38c8a6f2022-09-01 16:37:27 -07003434inline void handleSystemCollectionResetActionHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003435 crow::App& app, const crow::Request& req,
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003436 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3437 const std::string& /*systemId*/)
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003438{
3439 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3440 {
3441 return;
3442 }
3443 asyncResp->res.addHeader(
3444 boost::beast::http::field::link,
3445 "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3446}
3447
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303448/**
3449 * SystemResetActionInfo derived class for delivering Computer Systems
3450 * ResetType AllowableValues using ResetInfo schema.
3451 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003452inline void requestRoutesSystemResetActionInfo(App& app)
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303453{
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003454 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003455 .privileges(redfish::privileges::headActionInfo)
3456 .methods(boost::beast::http::verb::head)(std::bind_front(
3457 handleSystemCollectionResetActionHead, std::ref(app)));
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303458 /**
3459 * Functions triggers appropriate requests on DBus
3460 */
Ed Tanous22d268c2022-05-19 09:39:07 -07003461 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
Ed Tanoused398212021-06-09 17:05:54 -07003462 .privileges(redfish::privileges::getActionInfo)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003463 .methods(boost::beast::http::verb::get)(
Ed Tanous45ca1b82022-03-25 13:07:27 -07003464 [&app](const crow::Request& req,
Ed Tanous22d268c2022-05-19 09:39:07 -07003465 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3466 const std::string& systemName) {
Carson Labrado3ba00072022-06-06 19:40:56 +00003467 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -07003468 {
3469 return;
3470 }
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003471 if constexpr (bmcwebEnableMultiHost)
3472 {
3473 // Option currently returns no systems. TBD
3474 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3475 systemName);
3476 return;
3477 }
Asmitha Karunanithi746b56f2023-02-27 23:29:49 -06003478
3479 if (systemName == "hypervisor")
3480 {
3481 handleHypervisorResetActionGet(asyncResp);
3482 return;
3483 }
3484
Ed Tanous22d268c2022-05-19 09:39:07 -07003485 if (systemName != "system")
3486 {
3487 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3488 systemName);
3489 return;
3490 }
3491
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003492 asyncResp->res.addHeader(
3493 boost::beast::http::field::link,
3494 "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
Ed Tanous14766872022-03-15 10:44:42 -07003495
Ed Tanous002d39b2022-05-31 08:59:27 -07003496 asyncResp->res.jsonValue["@odata.id"] =
3497 "/redfish/v1/Systems/system/ResetActionInfo";
3498 asyncResp->res.jsonValue["@odata.type"] =
3499 "#ActionInfo.v1_1_2.ActionInfo";
3500 asyncResp->res.jsonValue["Name"] = "Reset Action Info";
3501 asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
Nan Zhou3215e702022-06-01 16:55:13 +00003502
3503 nlohmann::json::array_t parameters;
3504 nlohmann::json::object_t parameter;
3505
3506 parameter["Name"] = "ResetType";
3507 parameter["Required"] = true;
3508 parameter["DataType"] = "String";
3509 nlohmann::json::array_t allowableValues;
3510 allowableValues.emplace_back("On");
3511 allowableValues.emplace_back("ForceOff");
3512 allowableValues.emplace_back("ForceOn");
3513 allowableValues.emplace_back("ForceRestart");
3514 allowableValues.emplace_back("GracefulRestart");
3515 allowableValues.emplace_back("GracefulShutdown");
3516 allowableValues.emplace_back("PowerCycle");
3517 allowableValues.emplace_back("Nmi");
3518 parameter["AllowableValues"] = std::move(allowableValues);
3519 parameters.emplace_back(std::move(parameter));
3520
3521 asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
Ed Tanous002d39b2022-05-31 08:59:27 -07003522 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003523}
Ed Tanous1abe55e2018-09-05 08:30:59 -07003524} // namespace redfish