blob: 86730a5368bc01eae35b720ebc6e5d2e61326570 [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 Tanous002d39b2022-05-31 08:59:27 -07002836 sdbusplus::asio::getProperty<std::string>(
2837 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
2838 "/xyz/openbmc_project/network/hypervisor",
2839 "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08002840 [asyncResp](const boost::system::error_code& ec2,
Ed Tanous002d39b2022-05-31 08:59:27 -07002841 const std::string& /*hostName*/) {
2842 nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"];
2843 ifaceArray = nlohmann::json::array();
2844 auto& count = asyncResp->res.jsonValue["Members@odata.count"];
Ed Tanous14766872022-03-15 10:44:42 -07002845
Ed Tanous002d39b2022-05-31 08:59:27 -07002846 nlohmann::json::object_t system;
2847 system["@odata.id"] = "/redfish/v1/Systems/system";
Patrick Williamsb2ba3072023-05-12 10:27:39 -05002848 ifaceArray.emplace_back(std::move(system));
Ed Tanous002d39b2022-05-31 08:59:27 -07002849 count = ifaceArray.size();
Ed Tanous8a592812022-06-04 09:06:59 -07002850 if (!ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002851 {
2852 BMCWEB_LOG_DEBUG << "Hypervisor is available";
2853 nlohmann::json::object_t hypervisor;
2854 hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor";
Patrick Williamsb2ba3072023-05-12 10:27:39 -05002855 ifaceArray.emplace_back(std::move(hypervisor));
Ed Tanous002d39b2022-05-31 08:59:27 -07002856 count = ifaceArray.size();
2857 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002858 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002859 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002860}
Sunitha Harish462023a2020-02-19 08:34:59 -06002861
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002862/**
2863 * Function transceives data with dbus directly.
2864 */
Ed Tanous4f48d5f2021-06-21 08:27:45 -07002865inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002866{
Patrick Williams89492a12023-05-10 07:51:34 -05002867 constexpr const char* serviceName = "xyz.openbmc_project.Control.Host.NMI";
2868 constexpr const char* objectPath = "/xyz/openbmc_project/control/host0/nmi";
2869 constexpr const char* interfaceName =
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002870 "xyz.openbmc_project.Control.Host.NMI";
Patrick Williams89492a12023-05-10 07:51:34 -05002871 constexpr const char* method = "NMI";
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002872
2873 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08002874 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002875 if (ec)
2876 {
2877 BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
2878 messages::internalError(asyncResp->res);
2879 return;
2880 }
2881 messages::success(asyncResp->res);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002882 },
2883 serviceName, objectPath, interfaceName, method);
2884}
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002885
2886/**
Andrew Geisslerfc903b32023-05-31 14:15:42 -04002887 * Handle error responses from d-bus for system power requests
2888 */
2889inline void handleSystemActionResetError(const boost::system::error_code& ec,
2890 const sdbusplus::message_t& eMsg,
2891 std::string_view resetType,
2892 crow::Response& res)
2893{
2894 if (ec.value() == boost::asio::error::invalid_argument)
2895 {
2896 messages::actionParameterNotSupported(res, resetType, "Reset");
2897 return;
2898 }
2899
2900 if (eMsg.get_error() == nullptr)
2901 {
2902 BMCWEB_LOG_ERROR << "D-Bus response error: " << ec;
2903 messages::internalError(res);
2904 return;
2905 }
2906 std::string_view errorMessage = eMsg.get_error()->name;
2907
2908 // If operation failed due to BMC not being in Ready state, tell
2909 // user to retry in a bit
2910 if ((errorMessage ==
2911 std::string_view(
2912 "xyz.openbmc_project.State.Chassis.Error.BMCNotReady")) ||
2913 (errorMessage ==
2914 std::string_view("xyz.openbmc_project.State.Host.Error.BMCNotReady")))
2915 {
2916 BMCWEB_LOG_DEBUG << "BMC not ready, operation not allowed right now";
2917 messages::serviceTemporarilyUnavailable(res, "10");
2918 return;
2919 }
2920
2921 BMCWEB_LOG_ERROR << "System Action Reset transition fail " << ec
2922 << " sdbusplus:" << errorMessage;
2923 messages::internalError(res);
2924}
2925
2926/**
Ed Tanouscc340dd2018-08-29 13:43:38 -07002927 * SystemActionsReset class supports handle POST method for Reset action.
2928 * The class retrieves and sends data directly to D-Bus.
2929 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002930inline void requestRoutesSystemActionsReset(App& app)
Ed Tanouscc340dd2018-08-29 13:43:38 -07002931{
Ed Tanouscc340dd2018-08-29 13:43:38 -07002932 /**
2933 * Function handles POST method request.
2934 * Analyzes POST body message before sends Reset request data to D-Bus.
2935 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002936 BMCWEB_ROUTE(app,
2937 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/")
Ed Tanoused398212021-06-09 17:05:54 -07002938 .privileges(redfish::privileges::postComputerSystem)
Ed Tanous002d39b2022-05-31 08:59:27 -07002939 .methods(boost::beast::http::verb::post)(
2940 [&app](const crow::Request& req,
2941 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
Carson Labrado3ba00072022-06-06 19:40:56 +00002942 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -07002943 {
2944 return;
2945 }
2946 std::string resetType;
2947 if (!json_util::readJsonAction(req, asyncResp->res, "ResetType",
2948 resetType))
2949 {
2950 return;
2951 }
Ed Tanous9712f8a2018-09-21 13:38:49 -07002952
Ed Tanous002d39b2022-05-31 08:59:27 -07002953 // Get the command and host vs. chassis
2954 std::string command;
2955 bool hostCommand = true;
2956 if ((resetType == "On") || (resetType == "ForceOn"))
2957 {
2958 command = "xyz.openbmc_project.State.Host.Transition.On";
2959 hostCommand = true;
2960 }
2961 else if (resetType == "ForceOff")
2962 {
2963 command = "xyz.openbmc_project.State.Chassis.Transition.Off";
2964 hostCommand = false;
2965 }
2966 else if (resetType == "ForceRestart")
2967 {
2968 command =
2969 "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
2970 hostCommand = true;
2971 }
2972 else if (resetType == "GracefulShutdown")
2973 {
2974 command = "xyz.openbmc_project.State.Host.Transition.Off";
2975 hostCommand = true;
2976 }
2977 else if (resetType == "GracefulRestart")
2978 {
2979 command =
2980 "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
2981 hostCommand = true;
2982 }
2983 else if (resetType == "PowerCycle")
2984 {
2985 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
2986 hostCommand = true;
2987 }
2988 else if (resetType == "Nmi")
2989 {
2990 doNMI(asyncResp);
2991 return;
2992 }
2993 else
2994 {
2995 messages::actionParameterUnknown(asyncResp->res, "Reset",
2996 resetType);
2997 return;
2998 }
Ed Tanouscc340dd2018-08-29 13:43:38 -07002999
Ed Tanous002d39b2022-05-31 08:59:27 -07003000 if (hostCommand)
3001 {
3002 crow::connections::systemBus->async_method_call(
Andrew Geisslerfc903b32023-05-31 14:15:42 -04003003 [asyncResp, resetType](const boost::system::error_code& ec,
3004 sdbusplus::message_t& sdbusErrMsg) {
Ed Tanous002d39b2022-05-31 08:59:27 -07003005 if (ec)
3006 {
Andrew Geisslerfc903b32023-05-31 14:15:42 -04003007 handleSystemActionResetError(ec, sdbusErrMsg, resetType,
3008 asyncResp->res);
3009
Ed Tanous002d39b2022-05-31 08:59:27 -07003010 return;
3011 }
3012 messages::success(asyncResp->res);
3013 },
3014 "xyz.openbmc_project.State.Host",
3015 "/xyz/openbmc_project/state/host0",
3016 "org.freedesktop.DBus.Properties", "Set",
3017 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
3018 dbus::utility::DbusVariantType{command});
3019 }
3020 else
3021 {
3022 crow::connections::systemBus->async_method_call(
Andrew Geisslerfc903b32023-05-31 14:15:42 -04003023 [asyncResp, resetType](const boost::system::error_code& ec,
3024 sdbusplus::message_t& sdbusErrMsg) {
Ed Tanous002d39b2022-05-31 08:59:27 -07003025 if (ec)
3026 {
Andrew Geisslerfc903b32023-05-31 14:15:42 -04003027 handleSystemActionResetError(ec, sdbusErrMsg, resetType,
3028 asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07003029 return;
3030 }
3031 messages::success(asyncResp->res);
3032 },
3033 "xyz.openbmc_project.State.Chassis",
3034 "/xyz/openbmc_project/state/chassis0",
3035 "org.freedesktop.DBus.Properties", "Set",
3036 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
3037 dbus::utility::DbusVariantType{command});
3038 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003039 });
3040}
Ed Tanouscc340dd2018-08-29 13:43:38 -07003041
Ed Tanous38c8a6f2022-09-01 16:37:27 -07003042inline void handleComputerSystemCollectionHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003043 App& app, const crow::Request& req,
3044 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
3045{
3046 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3047 {
3048 return;
3049 }
3050
3051 asyncResp->res.addHeader(
3052 boost::beast::http::field::link,
3053 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3054}
3055
Abhishek Patel5c3e9272021-06-24 10:11:33 -05003056inline void afterPortRequest(
3057 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3058 const boost::system::error_code& ec,
3059 const std::vector<std::tuple<std::string, std::string, bool>>& socketData)
3060{
3061 if (ec)
3062 {
3063 messages::internalError(asyncResp->res);
3064 return;
3065 }
3066 for (const auto& data : socketData)
3067 {
3068 const std::string& socketPath = get<0>(data);
3069 const std::string& protocolName = get<1>(data);
3070 bool isProtocolEnabled = get<2>(data);
3071 nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"];
3072 dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled;
3073 // need to retrieve port number for
3074 // obmc-console-ssh service
3075 if (protocolName == "SSH")
3076 {
3077 getPortNumber(socketPath, [asyncResp, protocolName](
Ed Tanous81c4e332023-05-18 10:30:34 -07003078 const boost::system::error_code& ec1,
Abhishek Patel5c3e9272021-06-24 10:11:33 -05003079 int portNumber) {
3080 if (ec1)
3081 {
3082 messages::internalError(asyncResp->res);
3083 return;
3084 }
3085 nlohmann::json& dataJson1 =
3086 asyncResp->res.jsonValue["SerialConsole"];
3087 dataJson1[protocolName]["Port"] = portNumber;
3088 });
3089 }
3090 }
3091}
Ed Tanouscc340dd2018-08-29 13:43:38 -07003092/**
Ed Tanous66173382018-08-15 18:20:59 -07003093 * Systems derived class for delivering Computer Systems Schema.
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02003094 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003095inline void requestRoutesSystems(App& app)
Ed Tanous1abe55e2018-09-05 08:30:59 -07003096{
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003097 BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/")
3098 .privileges(redfish::privileges::headComputerSystem)
3099 .methods(boost::beast::http::verb::head)(
3100 std::bind_front(handleComputerSystemCollectionHead, std::ref(app)));
Ed Tanous1abe55e2018-09-05 08:30:59 -07003101 /**
3102 * Functions triggers appropriate requests on DBus
3103 */
Ed Tanous22d268c2022-05-19 09:39:07 -07003104 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07003105 .privileges(redfish::privileges::getComputerSystem)
Ed Tanous002d39b2022-05-31 08:59:27 -07003106 .methods(boost::beast::http::verb::get)(
3107 [&app](const crow::Request& req,
Ed Tanous22d268c2022-05-19 09:39:07 -07003108 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3109 const std::string& systemName) {
Carson Labrado3ba00072022-06-06 19:40:56 +00003110 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -07003111 {
3112 return;
3113 }
Asmitha Karunanithi746b56f2023-02-27 23:29:49 -06003114
3115 if (systemName == "hypervisor")
3116 {
3117 handleHypervisorSystemGet(asyncResp);
3118 return;
3119 }
3120
Ed Tanous22d268c2022-05-19 09:39:07 -07003121 if (systemName != "system")
3122 {
3123 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3124 systemName);
3125 return;
3126 }
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003127 asyncResp->res.addHeader(
3128 boost::beast::http::field::link,
3129 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
Ed Tanous002d39b2022-05-31 08:59:27 -07003130 asyncResp->res.jsonValue["@odata.type"] =
3131 "#ComputerSystem.v1_16_0.ComputerSystem";
3132 asyncResp->res.jsonValue["Name"] = "system";
3133 asyncResp->res.jsonValue["Id"] = "system";
3134 asyncResp->res.jsonValue["SystemType"] = "Physical";
3135 asyncResp->res.jsonValue["Description"] = "Computer System";
3136 asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -05003137 if constexpr (bmcwebEnableProcMemStatus)
3138 {
3139 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
3140 "Disabled";
3141 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
3142 "Disabled";
3143 }
Ninad Palsulecf0e0042023-05-18 17:18:09 -05003144 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
3145 uint64_t(0);
Ed Tanous002d39b2022-05-31 08:59:27 -07003146 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
Ed Tanous04a258f2018-10-15 08:00:41 -07003147
Ed Tanous002d39b2022-05-31 08:59:27 -07003148 asyncResp->res.jsonValue["Processors"]["@odata.id"] =
3149 "/redfish/v1/Systems/system/Processors";
3150 asyncResp->res.jsonValue["Memory"]["@odata.id"] =
3151 "/redfish/v1/Systems/system/Memory";
3152 asyncResp->res.jsonValue["Storage"]["@odata.id"] =
3153 "/redfish/v1/Systems/system/Storage";
Sunny Srivastava31791052021-03-12 10:39:16 -06003154 asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] =
3155 "/redfish/v1/Systems/system/FabricAdapters";
Ed Tanous029573d2019-02-01 10:57:49 -08003156
Ed Tanous002d39b2022-05-31 08:59:27 -07003157 asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] =
3158 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset";
3159 asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]
3160 ["@Redfish.ActionInfo"] =
3161 "/redfish/v1/Systems/system/ResetActionInfo";
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02003162
Ed Tanous002d39b2022-05-31 08:59:27 -07003163 asyncResp->res.jsonValue["LogServices"]["@odata.id"] =
3164 "/redfish/v1/Systems/system/LogServices";
3165 asyncResp->res.jsonValue["Bios"]["@odata.id"] =
3166 "/redfish/v1/Systems/system/Bios";
Jason M. Billsc4bf6372018-11-05 13:48:27 -08003167
Ed Tanous002d39b2022-05-31 08:59:27 -07003168 nlohmann::json::array_t managedBy;
3169 nlohmann::json& manager = managedBy.emplace_back();
3170 manager["@odata.id"] = "/redfish/v1/Managers/bmc";
3171 asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy);
3172 asyncResp->res.jsonValue["Status"]["Health"] = "OK";
3173 asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06003174
Ed Tanous002d39b2022-05-31 08:59:27 -07003175 // Fill in SerialConsole info
3176 asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15;
3177 asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] =
3178 true;
Ed Tanous14766872022-03-15 10:44:42 -07003179
Ed Tanous002d39b2022-05-31 08:59:27 -07003180 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] =
3181 true;
3182 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200;
3183 asyncResp->res
3184 .jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] =
3185 "Press ~. to exit console";
Abhishek Patel5c3e9272021-06-24 10:11:33 -05003186 getPortStatusAndPath(std::span{protocolToDBusForSystems},
3187 std::bind_front(afterPortRequest, asyncResp));
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06003188
3189#ifdef BMCWEB_ENABLE_KVM
Ed Tanous002d39b2022-05-31 08:59:27 -07003190 // Fill in GraphicalConsole info
3191 asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true;
3192 asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] =
3193 4;
Ed Tanous613dabe2022-07-09 11:17:36 -07003194 asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] =
3195 nlohmann::json::array_t({"KVMIP"});
Ed Tanous14766872022-03-15 10:44:42 -07003196
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06003197#endif // BMCWEB_ENABLE_KVM
James Feistb49ac872019-05-21 15:12:01 -07003198
Ed Tanous002d39b2022-05-31 08:59:27 -07003199 auto health = std::make_shared<HealthPopulate>(asyncResp);
Willy Tu13451e32023-05-24 16:08:18 -07003200 if constexpr (bmcwebEnableHealthPopulate)
3201 {
3202 constexpr std::array<std::string_view, 4> inventoryForSystems{
3203 "xyz.openbmc_project.Inventory.Item.Dimm",
3204 "xyz.openbmc_project.Inventory.Item.Cpu",
3205 "xyz.openbmc_project.Inventory.Item.Drive",
3206 "xyz.openbmc_project.Inventory.Item.StorageController"};
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003207
Willy Tu13451e32023-05-24 16:08:18 -07003208 dbus::utility::getSubTreePaths(
3209 "/", 0, inventoryForSystems,
3210 [health](const boost::system::error_code& ec,
3211 const std::vector<std::string>& resp) {
3212 if (ec)
3213 {
3214 // no inventory
3215 return;
3216 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003217
Willy Tu13451e32023-05-24 16:08:18 -07003218 health->inventory = resp;
3219 });
3220 health->populate();
3221 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003222
Ed Tanous002d39b2022-05-31 08:59:27 -07003223 getMainChassisId(asyncResp,
3224 [](const std::string& chassisId,
3225 const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
3226 nlohmann::json::array_t chassisArray;
3227 nlohmann::json& chassis = chassisArray.emplace_back();
Ed Tanousef4c65b2023-04-24 15:28:50 -07003228 chassis["@odata.id"] = boost::urls::format("/redfish/v1/Chassis/{}",
3229 chassisId);
Ed Tanous002d39b2022-05-31 08:59:27 -07003230 aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray);
3231 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003232
Ed Tanous002d39b2022-05-31 08:59:27 -07003233 getLocationIndicatorActive(asyncResp);
3234 // TODO (Gunnar): Remove IndicatorLED after enough time has passed
3235 getIndicatorLedState(asyncResp);
3236 getComputerSystem(asyncResp, health);
3237 getHostState(asyncResp);
3238 getBootProperties(asyncResp);
3239 getBootProgress(asyncResp);
Hieu Huynhb6d5d452022-10-07 09:41:46 +00003240 getBootProgressLastStateTime(asyncResp);
Lakshmi Yadlapati472bd202023-03-22 09:57:05 -05003241 pcie_util::getPCIeDeviceList(asyncResp, "PCIeDevices");
Ed Tanous002d39b2022-05-31 08:59:27 -07003242 getHostWatchdogTimer(asyncResp);
3243 getPowerRestorePolicy(asyncResp);
Corey Hardesty797d5da2022-04-26 17:54:52 +08003244 getAutomaticRetryPolicy(asyncResp);
Ed Tanous002d39b2022-05-31 08:59:27 -07003245 getLastResetTime(asyncResp);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003246#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
Ed Tanous002d39b2022-05-31 08:59:27 -07003247 getProvisioningStatus(asyncResp);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003248#endif
Ed Tanous002d39b2022-05-31 08:59:27 -07003249 getTrustedModuleRequiredToBoot(asyncResp);
3250 getPowerMode(asyncResp);
3251 getIdlePowerSaver(asyncResp);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003252 });
Jiaqing Zhao550a6bf2022-04-26 17:54:52 +08003253
Ed Tanous22d268c2022-05-19 09:39:07 -07003254 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07003255 .privileges(redfish::privileges::patchComputerSystem)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003256 .methods(boost::beast::http::verb::patch)(
Ed Tanous45ca1b82022-03-25 13:07:27 -07003257 [&app](const crow::Request& req,
Ed Tanous22d268c2022-05-19 09:39:07 -07003258 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3259 const std::string& systemName) {
Carson Labrado3ba00072022-06-06 19:40:56 +00003260 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -07003261 {
3262 return;
3263 }
Ed Tanous22d268c2022-05-19 09:39:07 -07003264 if (systemName != "system")
3265 {
3266 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3267 systemName);
3268 return;
3269 }
3270
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003271 asyncResp->res.addHeader(
3272 boost::beast::http::field::link,
3273 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3274
Ed Tanous002d39b2022-05-31 08:59:27 -07003275 std::optional<bool> locationIndicatorActive;
3276 std::optional<std::string> indicatorLed;
3277 std::optional<std::string> assetTag;
3278 std::optional<std::string> powerRestorePolicy;
3279 std::optional<std::string> powerMode;
3280 std::optional<bool> wdtEnable;
3281 std::optional<std::string> wdtTimeOutAction;
3282 std::optional<std::string> bootSource;
3283 std::optional<std::string> bootType;
3284 std::optional<std::string> bootEnable;
3285 std::optional<std::string> bootAutomaticRetry;
Corey Hardesty797d5da2022-04-26 17:54:52 +08003286 std::optional<uint32_t> bootAutomaticRetryAttempts;
Ed Tanous002d39b2022-05-31 08:59:27 -07003287 std::optional<bool> bootTrustedModuleRequired;
3288 std::optional<bool> ipsEnable;
3289 std::optional<uint8_t> ipsEnterUtil;
3290 std::optional<uint64_t> ipsEnterTime;
3291 std::optional<uint8_t> ipsExitUtil;
3292 std::optional<uint64_t> ipsExitTime;
Jiaqing Zhao550a6bf2022-04-26 17:54:52 +08003293
Ed Tanous002d39b2022-05-31 08:59:27 -07003294 // clang-format off
Ed Tanous22d268c2022-05-19 09:39:07 -07003295 if (!json_util::readJsonPatch(
3296 req, asyncResp->res,
3297 "IndicatorLED", indicatorLed,
3298 "LocationIndicatorActive", locationIndicatorActive,
3299 "AssetTag", assetTag,
3300 "PowerRestorePolicy", powerRestorePolicy,
3301 "PowerMode", powerMode,
3302 "HostWatchdogTimer/FunctionEnabled", wdtEnable,
3303 "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction,
3304 "Boot/BootSourceOverrideTarget", bootSource,
3305 "Boot/BootSourceOverrideMode", bootType,
3306 "Boot/BootSourceOverrideEnabled", bootEnable,
3307 "Boot/AutomaticRetryConfig", bootAutomaticRetry,
Corey Hardesty797d5da2022-04-26 17:54:52 +08003308 "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts,
Ed Tanous22d268c2022-05-19 09:39:07 -07003309 "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired,
3310 "IdlePowerSaver/Enabled", ipsEnable,
3311 "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil,
3312 "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime,
3313 "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil,
3314 "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime))
3315 {
3316 return;
3317 }
Ed Tanous002d39b2022-05-31 08:59:27 -07003318 // clang-format on
James Feistb49ac872019-05-21 15:12:01 -07003319
Ed Tanous002d39b2022-05-31 08:59:27 -07003320 asyncResp->res.result(boost::beast::http::status::no_content);
James Feistb49ac872019-05-21 15:12:01 -07003321
Ed Tanous002d39b2022-05-31 08:59:27 -07003322 if (assetTag)
3323 {
3324 setAssetTag(asyncResp, *assetTag);
3325 }
James Feistb49ac872019-05-21 15:12:01 -07003326
Ed Tanous002d39b2022-05-31 08:59:27 -07003327 if (wdtEnable || wdtTimeOutAction)
3328 {
3329 setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
3330 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003331
Ed Tanous002d39b2022-05-31 08:59:27 -07003332 if (bootSource || bootType || bootEnable)
3333 {
3334 setBootProperties(asyncResp, bootSource, bootType, bootEnable);
3335 }
3336 if (bootAutomaticRetry)
3337 {
3338 setAutomaticRetry(asyncResp, *bootAutomaticRetry);
3339 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003340
Corey Hardesty797d5da2022-04-26 17:54:52 +08003341 if (bootAutomaticRetryAttempts)
3342 {
3343 setAutomaticRetryAttempts(asyncResp,
3344 bootAutomaticRetryAttempts.value());
3345 }
3346
Ed Tanous002d39b2022-05-31 08:59:27 -07003347 if (bootTrustedModuleRequired)
3348 {
3349 setTrustedModuleRequiredToBoot(asyncResp,
3350 *bootTrustedModuleRequired);
3351 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003352
Ed Tanous002d39b2022-05-31 08:59:27 -07003353 if (locationIndicatorActive)
3354 {
3355 setLocationIndicatorActive(asyncResp, *locationIndicatorActive);
3356 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003357
Ed Tanous002d39b2022-05-31 08:59:27 -07003358 // TODO (Gunnar): Remove IndicatorLED after enough time has
3359 // passed
3360 if (indicatorLed)
3361 {
3362 setIndicatorLedState(asyncResp, *indicatorLed);
3363 asyncResp->res.addHeader(boost::beast::http::field::warning,
3364 "299 - \"IndicatorLED is deprecated. Use "
3365 "LocationIndicatorActive instead.\"");
3366 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003367
Ed Tanous002d39b2022-05-31 08:59:27 -07003368 if (powerRestorePolicy)
3369 {
3370 setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
3371 }
Chris Cain3a2d04242021-05-28 16:57:10 -05003372
Ed Tanous002d39b2022-05-31 08:59:27 -07003373 if (powerMode)
3374 {
3375 setPowerMode(asyncResp, *powerMode);
3376 }
Chris Cain37bbf982021-09-20 10:53:09 -05003377
Ed Tanous002d39b2022-05-31 08:59:27 -07003378 if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil ||
3379 ipsExitTime)
3380 {
3381 setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime,
3382 ipsExitUtil, ipsExitTime);
3383 }
3384 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003385}
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303386
Ed Tanous38c8a6f2022-09-01 16:37:27 -07003387inline void handleSystemCollectionResetActionHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003388 crow::App& app, const crow::Request& req,
3389 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
3390{
3391 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3392 {
3393 return;
3394 }
3395 asyncResp->res.addHeader(
3396 boost::beast::http::field::link,
3397 "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3398}
3399
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303400/**
3401 * SystemResetActionInfo derived class for delivering Computer Systems
3402 * ResetType AllowableValues using ResetInfo schema.
3403 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003404inline void requestRoutesSystemResetActionInfo(App& app)
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303405{
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003406 BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/ResetActionInfo/")
3407 .privileges(redfish::privileges::headActionInfo)
3408 .methods(boost::beast::http::verb::head)(std::bind_front(
3409 handleSystemCollectionResetActionHead, std::ref(app)));
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303410 /**
3411 * Functions triggers appropriate requests on DBus
3412 */
Ed Tanous22d268c2022-05-19 09:39:07 -07003413 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
Ed Tanoused398212021-06-09 17:05:54 -07003414 .privileges(redfish::privileges::getActionInfo)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003415 .methods(boost::beast::http::verb::get)(
Ed Tanous45ca1b82022-03-25 13:07:27 -07003416 [&app](const crow::Request& req,
Ed Tanous22d268c2022-05-19 09:39:07 -07003417 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3418 const std::string& systemName) {
Carson Labrado3ba00072022-06-06 19:40:56 +00003419 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -07003420 {
3421 return;
3422 }
Asmitha Karunanithi746b56f2023-02-27 23:29:49 -06003423
3424 if (systemName == "hypervisor")
3425 {
3426 handleHypervisorResetActionGet(asyncResp);
3427 return;
3428 }
3429
Ed Tanous22d268c2022-05-19 09:39:07 -07003430 if (systemName != "system")
3431 {
3432 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3433 systemName);
3434 return;
3435 }
3436
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003437 asyncResp->res.addHeader(
3438 boost::beast::http::field::link,
3439 "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
Ed Tanous14766872022-03-15 10:44:42 -07003440
Ed Tanous002d39b2022-05-31 08:59:27 -07003441 asyncResp->res.jsonValue["@odata.id"] =
3442 "/redfish/v1/Systems/system/ResetActionInfo";
3443 asyncResp->res.jsonValue["@odata.type"] =
3444 "#ActionInfo.v1_1_2.ActionInfo";
3445 asyncResp->res.jsonValue["Name"] = "Reset Action Info";
3446 asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
Nan Zhou3215e702022-06-01 16:55:13 +00003447
3448 nlohmann::json::array_t parameters;
3449 nlohmann::json::object_t parameter;
3450
3451 parameter["Name"] = "ResetType";
3452 parameter["Required"] = true;
3453 parameter["DataType"] = "String";
3454 nlohmann::json::array_t allowableValues;
3455 allowableValues.emplace_back("On");
3456 allowableValues.emplace_back("ForceOff");
3457 allowableValues.emplace_back("ForceOn");
3458 allowableValues.emplace_back("ForceRestart");
3459 allowableValues.emplace_back("GracefulRestart");
3460 allowableValues.emplace_back("GracefulShutdown");
3461 allowableValues.emplace_back("PowerCycle");
3462 allowableValues.emplace_back("Nmi");
3463 parameter["AllowableValues"] = std::move(allowableValues);
3464 parameters.emplace_back(std::move(parameter));
3465
3466 asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
Ed Tanous002d39b2022-05-31 08:59:27 -07003467 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003468}
Ed Tanous1abe55e2018-09-05 08:30:59 -07003469} // namespace redfish