blob: e9ccde177e2e637be0c887093bdbb0ecec814e61 [file] [log] [blame]
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001/*
2// Copyright (c) 2018 Intel Corporation
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15*/
16#pragma once
17
James Feistb49ac872019-05-21 15:12:01 -070018#include "health.hpp"
Jason M. Billsf5c9f8b2018-12-18 16:51:18 -080019#include "pcie.hpp"
Jennifer Leec5d03ff2019-03-08 15:42:58 -080020#include "redfish_util.hpp"
21
Ed Tanous9712f8a2018-09-21 13:38:49 -070022#include <boost/container/flat_map.hpp>
23#include <node.hpp>
Andrew Geisslercb7e1e72019-02-19 13:05:38 -060024#include <utils/fw_utils.hpp>
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020025#include <utils/json_utils.hpp>
Ed Tanousabf2add2019-01-22 16:40:12 -080026#include <variant>
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020027
Ed Tanous1abe55e2018-09-05 08:30:59 -070028namespace redfish
29{
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020030
Alpana Kumari9d3ae102019-04-12 06:49:32 -050031/**
32 * @brief Updates the Functional State of DIMMs
33 *
34 * @param[in] aResp Shared pointer for completing asynchronous calls
35 * @param[in] dimmState Dimm's Functional state, true/false
36 *
37 * @return None.
38 */
39void updateDimmProperties(std::shared_ptr<AsyncResp> aResp,
40 const std::variant<bool> &dimmState)
41{
42 const bool *isDimmFunctional = std::get_if<bool>(&dimmState);
43 if (isDimmFunctional == nullptr)
44 {
45 messages::internalError(aResp->res);
46 return;
47 }
Gunnar Mills698654b2019-10-16 13:17:37 -050048 BMCWEB_LOG_DEBUG << "Dimm Functional: " << *isDimmFunctional;
Alpana Kumari9d3ae102019-04-12 06:49:32 -050049
50 // Set it as Enabled if atleast one DIMM is functional
51 // Update STATE only if previous State was DISABLED and current Dimm is
52 // ENABLED.
53 nlohmann::json &prevMemSummary =
54 aResp->res.jsonValue["MemorySummary"]["Status"]["State"];
55 if (prevMemSummary == "Disabled")
56 {
57 if (*isDimmFunctional == true)
58 {
59 aResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
60 "Enabled";
61 }
62 }
63}
64
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050065/*
66 * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState
67 *
68 * @param[in] aResp Shared pointer for completing asynchronous calls
69 * @param[in] cpuPresenceState CPU present or not
70 *
71 * @return None.
72 */
73void modifyCpuPresenceState(std::shared_ptr<AsyncResp> aResp,
74 const std::variant<bool> &cpuPresenceState)
75{
76 const bool *isCpuPresent = std::get_if<bool>(&cpuPresenceState);
77
78 if (isCpuPresent == nullptr)
79 {
80 messages::internalError(aResp->res);
81 return;
82 }
Gunnar Mills698654b2019-10-16 13:17:37 -050083 BMCWEB_LOG_DEBUG << "Cpu Present: " << *isCpuPresent;
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050084
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050085 if (*isCpuPresent == true)
86 {
James Feistb4b95952019-12-05 15:01:55 -080087 nlohmann::json &procCount =
88 aResp->res.jsonValue["ProcessorSummary"]["Count"];
89 auto procCountPtr =
90 procCount.get_ptr<nlohmann::json::number_integer_t *>();
91 if (procCountPtr != nullptr)
92 {
93 // shouldn't be possible to be nullptr
94 *procCountPtr += 1;
95 }
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050096 }
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050097}
98
99/*
100 * @brief Update "ProcessorSummary" "Status" "State" based on
101 * CPU Functional State
102 *
103 * @param[in] aResp Shared pointer for completing asynchronous calls
104 * @param[in] cpuFunctionalState is CPU functional true/false
105 *
106 * @return None.
107 */
108void modifyCpuFunctionalState(std::shared_ptr<AsyncResp> aResp,
109 const std::variant<bool> &cpuFunctionalState)
110{
111 const bool *isCpuFunctional = std::get_if<bool>(&cpuFunctionalState);
112
113 if (isCpuFunctional == nullptr)
114 {
115 messages::internalError(aResp->res);
116 return;
117 }
Gunnar Mills698654b2019-10-16 13:17:37 -0500118 BMCWEB_LOG_DEBUG << "Cpu Functional: " << *isCpuFunctional;
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500119
120 nlohmann::json &prevProcState =
121 aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"];
122
123 // Set it as Enabled if atleast one CPU is functional
124 // Update STATE only if previous State was Non_Functional and current CPU is
125 // Functional.
126 if (prevProcState == "Disabled")
127 {
128 if (*isCpuFunctional == true)
129 {
130 aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
131 "Enabled";
132 }
133 }
134}
135
136/*
Ed Tanous6c34de42018-08-29 13:37:36 -0700137 * @brief Retrieves computer system properties over dbus
138 *
139 * @param[in] aResp Shared pointer for completing asynchronous calls
140 * @param[in] name Computer system name from request
141 *
142 * @return None.
143 */
James Feist5bc2dc82019-10-22 14:33:16 -0700144void getComputerSystem(std::shared_ptr<AsyncResp> aResp,
145 std::shared_ptr<HealthPopulate> systemHealth)
Ed Tanous6c34de42018-08-29 13:37:36 -0700146{
Ed Tanous6c34de42018-08-29 13:37:36 -0700147 BMCWEB_LOG_DEBUG << "Get available system components.";
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500148
Ed Tanous6c34de42018-08-29 13:37:36 -0700149 crow::connections::systemBus->async_method_call(
James Feist5bc2dc82019-10-22 14:33:16 -0700150 [aResp, systemHealth](
Ed Tanous6c34de42018-08-29 13:37:36 -0700151 const boost::system::error_code ec,
152 const std::vector<std::pair<
153 std::string,
154 std::vector<std::pair<std::string, std::vector<std::string>>>>>
155 &subtree) {
156 if (ec)
157 {
158 BMCWEB_LOG_DEBUG << "DBUS response error";
Jason M. Billsf12894f2018-10-09 12:45:45 -0700159 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700160 return;
161 }
Ed Tanous6c34de42018-08-29 13:37:36 -0700162 // Iterate over all retrieved ObjectPaths.
163 for (const std::pair<std::string,
164 std::vector<std::pair<
165 std::string, std::vector<std::string>>>>
166 &object : subtree)
167 {
168 const std::string &path = object.first;
169 BMCWEB_LOG_DEBUG << "Got path: " << path;
170 const std::vector<
171 std::pair<std::string, std::vector<std::string>>>
172 &connectionNames = object.second;
173 if (connectionNames.size() < 1)
174 {
175 continue;
176 }
Ed Tanous029573d2019-02-01 10:57:49 -0800177
James Feist5bc2dc82019-10-22 14:33:16 -0700178 auto memoryHealth = std::make_shared<HealthPopulate>(
179 aResp, aResp->res.jsonValue["MemorySummary"]["Status"]);
180
181 auto cpuHealth = std::make_shared<HealthPopulate>(
182 aResp, aResp->res.jsonValue["ProcessorSummary"]["Status"]);
183
184 systemHealth->children.emplace_back(memoryHealth);
185 systemHealth->children.emplace_back(cpuHealth);
186
Ed Tanous029573d2019-02-01 10:57:49 -0800187 // This is not system, so check if it's cpu, dimm, UUID or
188 // BiosVer
189 for (const auto &connection : connectionNames)
Ed Tanous6c34de42018-08-29 13:37:36 -0700190 {
Ed Tanous029573d2019-02-01 10:57:49 -0800191 for (const auto &interfaceName : connection.second)
Ed Tanous6c34de42018-08-29 13:37:36 -0700192 {
Ed Tanous029573d2019-02-01 10:57:49 -0800193 if (interfaceName ==
194 "xyz.openbmc_project.Inventory.Item.Dimm")
Ed Tanous6c34de42018-08-29 13:37:36 -0700195 {
Ed Tanous029573d2019-02-01 10:57:49 -0800196 BMCWEB_LOG_DEBUG
197 << "Found Dimm, now get its properties.";
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500198
Ed Tanous029573d2019-02-01 10:57:49 -0800199 crow::connections::systemBus->async_method_call(
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500200 [aResp, service{connection.first},
201 path(std::move(path))](
202 const boost::system::error_code ec,
203 const std::vector<
204 std::pair<std::string, VariantType>>
205 &properties) {
Ed Tanous029573d2019-02-01 10:57:49 -0800206 if (ec)
207 {
208 BMCWEB_LOG_ERROR
209 << "DBUS response error " << ec;
210 messages::internalError(aResp->res);
211 return;
212 }
213 BMCWEB_LOG_DEBUG << "Got "
214 << properties.size()
Gunnar Mills698654b2019-10-16 13:17:37 -0500215 << " Dimm properties.";
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500216
217 if (properties.size() > 0)
Ed Tanous029573d2019-02-01 10:57:49 -0800218 {
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500219 for (const std::pair<std::string,
220 VariantType>
221 &property : properties)
Ed Tanous6c34de42018-08-29 13:37:36 -0700222 {
Cheng C Yang5fd7ba62019-11-28 15:58:08 +0800223 if (property.first !=
224 "MemorySizeInKB")
Ed Tanous6c34de42018-08-29 13:37:36 -0700225 {
Cheng C Yang5fd7ba62019-11-28 15:58:08 +0800226 continue;
Ed Tanous6c34de42018-08-29 13:37:36 -0700227 }
Cheng C Yang5fd7ba62019-11-28 15:58:08 +0800228 const uint32_t *value =
229 sdbusplus::message::variant_ns::
230 get_if<uint32_t>(
231 &property.second);
232 if (value == nullptr)
233 {
234 BMCWEB_LOG_DEBUG
235 << "Find incorrect type of "
236 "MemorySize";
237 continue;
238 }
239 nlohmann::json &totalMemory =
240 aResp->res
241 .jsonValue["MemorySummar"
242 "y"]
243 ["TotalSystemMe"
244 "moryGiB"];
245 uint64_t *preValue =
246 totalMemory
247 .get_ptr<uint64_t *>();
248 if (preValue == nullptr)
249 {
250 continue;
251 }
252 aResp->res
253 .jsonValue["MemorySummary"]
254 ["TotalSystemMemoryGi"
255 "B"] =
256 *value / (1024 * 1024) +
257 *preValue;
258 aResp->res
259 .jsonValue["MemorySummary"]
260 ["Status"]["State"] =
261 "Enabled";
Ed Tanous6c34de42018-08-29 13:37:36 -0700262 }
Ed Tanous029573d2019-02-01 10:57:49 -0800263 }
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500264 else
265 {
266 auto getDimmProperties =
267 [aResp](
268 const boost::system::error_code
269 ec,
270 const std::variant<bool>
271 &dimmState) {
272 if (ec)
273 {
274 BMCWEB_LOG_ERROR
275 << "DBUS response "
276 "error "
277 << ec;
278 return;
279 }
280 updateDimmProperties(aResp,
281 dimmState);
282 };
283 crow::connections::systemBus
284 ->async_method_call(
285 std::move(getDimmProperties),
286 service, path,
287 "org.freedesktop.DBus."
288 "Properties",
289 "Get",
290 "xyz.openbmc_project.State."
291 "Decorator.OperationalStatus",
292 "Functional");
293 }
Ed Tanous029573d2019-02-01 10:57:49 -0800294 },
295 connection.first, path,
296 "org.freedesktop.DBus.Properties", "GetAll",
297 "xyz.openbmc_project.Inventory.Item.Dimm");
James Feist5bc2dc82019-10-22 14:33:16 -0700298
299 memoryHealth->inventory.emplace_back(path);
Ed Tanous029573d2019-02-01 10:57:49 -0800300 }
301 else if (interfaceName ==
302 "xyz.openbmc_project.Inventory.Item.Cpu")
303 {
304 BMCWEB_LOG_DEBUG
305 << "Found Cpu, now get its properties.";
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500306
Ed Tanous029573d2019-02-01 10:57:49 -0800307 crow::connections::systemBus->async_method_call(
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500308 [aResp, service{connection.first},
309 path(std::move(path))](
310 const boost::system::error_code ec,
311 const std::vector<
312 std::pair<std::string, VariantType>>
313 &properties) {
Ed Tanous029573d2019-02-01 10:57:49 -0800314 if (ec)
315 {
316 BMCWEB_LOG_ERROR
317 << "DBUS response error " << ec;
318 messages::internalError(aResp->res);
319 return;
320 }
321 BMCWEB_LOG_DEBUG << "Got "
322 << properties.size()
Gunnar Mills698654b2019-10-16 13:17:37 -0500323 << " Cpu properties.";
Ed Tanous04a258f2018-10-15 08:00:41 -0700324
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500325 if (properties.size() > 0)
326 {
327 for (const auto &property : properties)
328 {
329 if (property.first ==
330 "ProcessorFamily")
331 {
332 const std::string *value =
333 sdbusplus::message::
334 variant_ns::get_if<
335 std::string>(
336 &property.second);
337 if (value != nullptr)
338 {
339 nlohmann::json
340 &procSummary =
341 aResp->res.jsonValue
342 ["ProcessorSumm"
343 "ary"];
344 nlohmann::json &procCount =
345 procSummary["Count"];
James Feistb4b95952019-12-05 15:01:55 -0800346
347 auto procCountPtr =
348 procCount.get_ptr<
349 nlohmann::json::
350 number_integer_t
351 *>();
352 if (procCountPtr != nullptr)
353 {
354 // shouldn't be possible
355 // to be nullptr
356 *procCountPtr += 1;
357 }
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500358 procSummary["Status"]
359 ["State"] =
360 "Enabled";
361 procSummary["Model"] =
362 *value;
363 }
Ed Tanous6c34de42018-08-29 13:37:36 -0700364 }
365 }
Ed Tanous029573d2019-02-01 10:57:49 -0800366 }
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500367 else
368 {
369 auto getCpuPresenceState =
370 [aResp](
371 const boost::system::error_code
372 ec,
373 const std::variant<bool>
374 &cpuPresenceCheck) {
375 if (ec)
376 {
377 BMCWEB_LOG_ERROR
378 << "DBUS response "
379 "error "
380 << ec;
381 return;
382 }
383 modifyCpuPresenceState(
384 aResp, cpuPresenceCheck);
385 };
386
387 auto getCpuFunctionalState =
388 [aResp](
389 const boost::system::error_code
390 ec,
391 const std::variant<bool>
392 &cpuFunctionalCheck) {
393 if (ec)
394 {
395 BMCWEB_LOG_ERROR
396 << "DBUS response "
397 "error "
398 << ec;
399 return;
400 }
401 modifyCpuFunctionalState(
402 aResp, cpuFunctionalCheck);
403 };
404 // Get the Presence of CPU
405 crow::connections::systemBus
406 ->async_method_call(
407 std::move(getCpuPresenceState),
408 service, path,
409 "org.freedesktop.DBus."
410 "Properties",
411 "Get",
412 "xyz.openbmc_project.Inventory."
413 "Item",
414 "Present");
415
416 // Get the Functional State
417 crow::connections::systemBus
418 ->async_method_call(
419 std::move(
420 getCpuFunctionalState),
421 service, path,
422 "org.freedesktop.DBus."
423 "Properties",
424 "Get",
425 "xyz.openbmc_project.State."
426 "Decorator."
427 "OperationalStatus",
428 "Functional");
429
430 // Get the MODEL from
431 // xyz.openbmc_project.Inventory.Decorator.Asset
432 // support it later as Model is Empty
433 // currently.
434 }
Ed Tanous029573d2019-02-01 10:57:49 -0800435 },
436 connection.first, path,
437 "org.freedesktop.DBus.Properties", "GetAll",
438 "xyz.openbmc_project.Inventory.Item.Cpu");
James Feist5bc2dc82019-10-22 14:33:16 -0700439
440 cpuHealth->inventory.emplace_back(path);
Ed Tanous029573d2019-02-01 10:57:49 -0800441 }
442 else if (interfaceName ==
443 "xyz.openbmc_project.Common.UUID")
444 {
445 BMCWEB_LOG_DEBUG
446 << "Found UUID, now get its properties.";
447 crow::connections::systemBus->async_method_call(
448 [aResp](const boost::system::error_code ec,
Ed Tanous6c34de42018-08-29 13:37:36 -0700449 const std::vector<
450 std::pair<std::string, VariantType>>
451 &properties) {
Ed Tanous029573d2019-02-01 10:57:49 -0800452 if (ec)
453 {
454 BMCWEB_LOG_DEBUG
455 << "DBUS response error " << ec;
456 messages::internalError(aResp->res);
457 return;
458 }
459 BMCWEB_LOG_DEBUG << "Got "
460 << properties.size()
Gunnar Mills698654b2019-10-16 13:17:37 -0500461 << " UUID properties.";
Ed Tanous029573d2019-02-01 10:57:49 -0800462 for (const std::pair<std::string,
463 VariantType>
464 &property : properties)
465 {
Ed Tanous029573d2019-02-01 10:57:49 -0800466 if (property.first == "UUID")
467 {
468 const std::string *value =
469 sdbusplus::message::variant_ns::
470 get_if<std::string>(
471 &property.second);
Ed Tanous04a258f2018-10-15 08:00:41 -0700472
Ed Tanous029573d2019-02-01 10:57:49 -0800473 if (value != nullptr)
474 {
475 std::string valueStr = *value;
476 if (valueStr.size() == 32)
Ed Tanous6c34de42018-08-29 13:37:36 -0700477 {
Ed Tanous029573d2019-02-01 10:57:49 -0800478 valueStr.insert(8, 1, '-');
479 valueStr.insert(13, 1, '-');
480 valueStr.insert(18, 1, '-');
481 valueStr.insert(23, 1, '-');
Ed Tanous6c34de42018-08-29 13:37:36 -0700482 }
Ed Tanous029573d2019-02-01 10:57:49 -0800483 BMCWEB_LOG_DEBUG << "UUID = "
484 << valueStr;
485 aResp->res.jsonValue["UUID"] =
486 valueStr;
Ed Tanous6c34de42018-08-29 13:37:36 -0700487 }
488 }
Ed Tanous029573d2019-02-01 10:57:49 -0800489 }
490 },
491 connection.first, path,
492 "org.freedesktop.DBus.Properties", "GetAll",
493 "xyz.openbmc_project.Common.UUID");
494 }
495 else if (interfaceName ==
496 "xyz.openbmc_project.Inventory.Item.System")
497 {
498 crow::connections::systemBus->async_method_call(
499 [aResp](const boost::system::error_code ec,
500 const std::vector<
501 std::pair<std::string, VariantType>>
502 &propertiesList) {
503 if (ec)
504 {
James Feiste4a4b9a2019-06-20 14:08:07 -0700505 // doesn't have to include this
506 // interface
Ed Tanous029573d2019-02-01 10:57:49 -0800507 return;
508 }
Gunnar Mills698654b2019-10-16 13:17:37 -0500509 BMCWEB_LOG_DEBUG
510 << "Got " << propertiesList.size()
511 << " properties for system";
Ed Tanous029573d2019-02-01 10:57:49 -0800512 for (const std::pair<std::string,
513 VariantType>
514 &property : propertiesList)
515 {
beccabroekfc5afcf2019-03-05 14:35:15 -0600516 const std::string &propertyName =
517 property.first;
518 if ((propertyName == "PartNumber") ||
519 (propertyName == "SerialNumber") ||
520 (propertyName == "Manufacturer") ||
521 (propertyName == "Model"))
Ed Tanous029573d2019-02-01 10:57:49 -0800522 {
beccabroekfc5afcf2019-03-05 14:35:15 -0600523 const std::string *value =
524 std::get_if<std::string>(
525 &property.second);
526 if (value != nullptr)
527 {
528 aResp->res
529 .jsonValue[propertyName] =
530 *value;
531 }
Ed Tanous029573d2019-02-01 10:57:49 -0800532 }
533 }
534 aResp->res.jsonValue["Name"] = "system";
535 aResp->res.jsonValue["Id"] =
536 aResp->res.jsonValue["SerialNumber"];
Andrew Geisslercb7e1e72019-02-19 13:05:38 -0600537 // Grab the bios version
538 fw_util::getActiveFwVersion(
539 aResp, fw_util::biosPurpose,
540 "BiosVersion");
Ed Tanous029573d2019-02-01 10:57:49 -0800541 },
542 connection.first, path,
543 "org.freedesktop.DBus.Properties", "GetAll",
544 "xyz.openbmc_project.Inventory.Decorator."
545 "Asset");
James Feiste4a4b9a2019-06-20 14:08:07 -0700546
547 crow::connections::systemBus->async_method_call(
548 [aResp](
549 const boost::system::error_code ec,
550 const std::variant<std::string> &property) {
551 if (ec)
552 {
553 // doesn't have to include this
554 // interface
555 return;
556 }
557
558 const std::string *value =
559 std::get_if<std::string>(&property);
560 if (value != nullptr)
561 {
562 aResp->res.jsonValue["AssetTag"] =
563 *value;
564 }
565 },
566 connection.first, path,
567 "org.freedesktop.DBus.Properties", "Get",
568 "xyz.openbmc_project.Inventory.Decorator."
569 "AssetTag",
570 "AssetTag");
Ed Tanous6c34de42018-08-29 13:37:36 -0700571 }
572 }
573 }
574 }
Ed Tanous6c34de42018-08-29 13:37:36 -0700575 },
576 "xyz.openbmc_project.ObjectMapper",
577 "/xyz/openbmc_project/object_mapper",
578 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
Ed Tanous66173382018-08-15 18:20:59 -0700579 "/xyz/openbmc_project/inventory", int32_t(0),
580 std::array<const char *, 5>{
581 "xyz.openbmc_project.Inventory.Decorator.Asset",
582 "xyz.openbmc_project.Inventory.Item.Cpu",
583 "xyz.openbmc_project.Inventory.Item.Dimm",
584 "xyz.openbmc_project.Inventory.Item.System",
585 "xyz.openbmc_project.Common.UUID",
586 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700587}
588
589/**
590 * @brief Retrieves identify led group properties over dbus
591 *
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530592 * @param[in] aResp Shared pointer for generating response message.
Ed Tanous6c34de42018-08-29 13:37:36 -0700593 *
594 * @return None.
595 */
AppaRao Pulia3002222019-11-12 21:32:59 +0530596void getIndicatorLedState(std::shared_ptr<AsyncResp> aResp)
Ed Tanous6c34de42018-08-29 13:37:36 -0700597{
598 BMCWEB_LOG_DEBUG << "Get led groups";
599 crow::connections::systemBus->async_method_call(
AppaRao Pulia3002222019-11-12 21:32:59 +0530600 [aResp](const boost::system::error_code ec,
601 const std::variant<bool> asserted) {
AppaRao Pulif847a192019-11-15 14:57:44 +0530602 // Some systems may not have enclosure_identify_blink object so
603 // proceed to get enclosure_identify state.
604 if (!ec)
Ed Tanous6c34de42018-08-29 13:37:36 -0700605 {
AppaRao Pulif847a192019-11-15 14:57:44 +0530606 const bool *blinking = std::get_if<bool>(&asserted);
607 if (!blinking)
608 {
609 BMCWEB_LOG_DEBUG << "Get identity blinking LED failed";
610 messages::internalError(aResp->res);
611 return;
612 }
613 // Blinking ON, no need to check enclosure_identify assert.
614 if (*blinking)
615 {
616 aResp->res.jsonValue["IndicatorLED"] = "Blinking";
617 return;
618 }
AppaRao Pulia3002222019-11-12 21:32:59 +0530619 }
620 crow::connections::systemBus->async_method_call(
621 [aResp](const boost::system::error_code ec,
622 const std::variant<bool> asserted) {
AppaRao Pulif847a192019-11-15 14:57:44 +0530623 if (!ec)
Ed Tanous6c34de42018-08-29 13:37:36 -0700624 {
AppaRao Pulif847a192019-11-15 14:57:44 +0530625 const bool *ledOn = std::get_if<bool>(&asserted);
626 if (!ledOn)
627 {
628 BMCWEB_LOG_DEBUG
629 << "Get enclosure identity led failed";
630 messages::internalError(aResp->res);
631 return;
632 }
AppaRao Pulia3002222019-11-12 21:32:59 +0530633
AppaRao Pulif847a192019-11-15 14:57:44 +0530634 if (*ledOn)
635 {
636 aResp->res.jsonValue["IndicatorLED"] = "Lit";
637 }
638 else
639 {
640 aResp->res.jsonValue["IndicatorLED"] = "Off";
641 }
AppaRao Pulia3002222019-11-12 21:32:59 +0530642 }
643 return;
644 },
645 "xyz.openbmc_project.LED.GroupManager",
646 "/xyz/openbmc_project/led/groups/enclosure_identify",
647 "org.freedesktop.DBus.Properties", "Get",
648 "xyz.openbmc_project.Led.Group", "Asserted");
649 },
650 "xyz.openbmc_project.LED.GroupManager",
651 "/xyz/openbmc_project/led/groups/enclosure_identify_blink",
652 "org.freedesktop.DBus.Properties", "Get",
653 "xyz.openbmc_project.Led.Group", "Asserted");
654}
655/**
656 * @brief Sets identify led group properties
657 *
658 * @param[in] aResp Shared pointer for generating response message.
659 * @param[in] ledState LED state passed from request
660 *
661 * @return None.
662 */
663void setIndicatorLedState(std::shared_ptr<AsyncResp> aResp,
664 const std::string &ledState)
665{
666 BMCWEB_LOG_DEBUG << "Set led groups";
667 bool ledOn = false;
668 bool ledBlinkng = false;
669
670 if (ledState == "Lit")
671 {
672 ledOn = true;
673 }
674 else if (ledState == "Blinking")
675 {
676 ledBlinkng = true;
677 }
678 else if (ledState != "Off")
679 {
680 messages::propertyValueNotInList(aResp->res, ledState, "IndicatorLED");
681 return;
682 }
683
684 crow::connections::systemBus->async_method_call(
AppaRao Pulif847a192019-11-15 14:57:44 +0530685 [aResp, ledOn, ledBlinkng](const boost::system::error_code ec,
686 const std::variant<bool> asserted) mutable {
AppaRao Pulia3002222019-11-12 21:32:59 +0530687 if (ec)
688 {
AppaRao Pulif847a192019-11-15 14:57:44 +0530689 // Some systems may not have enclosure_identify_blink object so
690 // Lets set enclosure_identify state to true if Blinking is
691 // true.
692 if (ledBlinkng)
693 {
694 ledOn = true;
695 }
Ed Tanous6c34de42018-08-29 13:37:36 -0700696 }
AppaRao Pulif847a192019-11-15 14:57:44 +0530697 crow::connections::systemBus->async_method_call(
698 [aResp](const boost::system::error_code ec,
699 const std::variant<bool> asserted) {
700 if (ec)
701 {
702 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
703 messages::internalError(aResp->res);
704 return;
705 }
706 },
707 "xyz.openbmc_project.LED.GroupManager",
708 "/xyz/openbmc_project/led/groups/enclosure_identify",
709 "org.freedesktop.DBus.Properties", "Set",
710 "xyz.openbmc_project.Led.Group", "Asserted",
711 std::variant<bool>(ledOn));
AppaRao Pulia3002222019-11-12 21:32:59 +0530712 },
713 "xyz.openbmc_project.LED.GroupManager",
714 "/xyz/openbmc_project/led/groups/enclosure_identify_blink",
715 "org.freedesktop.DBus.Properties", "Set",
716 "xyz.openbmc_project.Led.Group", "Asserted",
717 std::variant<bool>(ledBlinkng));
Ed Tanous6c34de42018-08-29 13:37:36 -0700718}
719
Ed Tanous6c34de42018-08-29 13:37:36 -0700720/**
721 * @brief Retrieves host state properties over dbus
722 *
723 * @param[in] aResp Shared pointer for completing asynchronous calls.
724 *
725 * @return None.
726 */
727void getHostState(std::shared_ptr<AsyncResp> aResp)
728{
729 BMCWEB_LOG_DEBUG << "Get host information.";
730 crow::connections::systemBus->async_method_call(
Jennifer Leec5d03ff2019-03-08 15:42:58 -0800731 [aResp](const boost::system::error_code ec,
732 const std::variant<std::string> &hostState) {
Ed Tanous6c34de42018-08-29 13:37:36 -0700733 if (ec)
734 {
735 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700736 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700737 return;
738 }
Ed Tanous66173382018-08-15 18:20:59 -0700739
Ed Tanousabf2add2019-01-22 16:40:12 -0800740 const std::string *s = std::get_if<std::string>(&hostState);
Ed Tanous66173382018-08-15 18:20:59 -0700741 BMCWEB_LOG_DEBUG << "Host state: " << *s;
742 if (s != nullptr)
Ed Tanous6c34de42018-08-29 13:37:36 -0700743 {
Ed Tanous66173382018-08-15 18:20:59 -0700744 // Verify Host State
Andrew Geissler94732662019-01-08 19:32:16 -0800745 if (*s == "xyz.openbmc_project.State.Host.HostState.Running")
Ed Tanous6c34de42018-08-29 13:37:36 -0700746 {
Ed Tanous66173382018-08-15 18:20:59 -0700747 aResp->res.jsonValue["PowerState"] = "On";
748 aResp->res.jsonValue["Status"]["State"] = "Enabled";
749 }
750 else
751 {
752 aResp->res.jsonValue["PowerState"] = "Off";
753 aResp->res.jsonValue["Status"]["State"] = "Disabled";
Ed Tanous6c34de42018-08-29 13:37:36 -0700754 }
755 }
756 },
757 "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
Ed Tanous66173382018-08-15 18:20:59 -0700758 "org.freedesktop.DBus.Properties", "Get",
759 "xyz.openbmc_project.State.Host", "CurrentHostState");
Ed Tanous6c34de42018-08-29 13:37:36 -0700760}
761
762/**
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530763 * @brief Traslates boot source DBUS property value to redfish.
764 *
765 * @param[in] dbusSource The boot source in DBUS speak.
766 *
767 * @return Returns as a string, the boot source in Redfish terms. If translation
768 * cannot be done, returns an empty string.
769 */
770static std::string dbusToRfBootSource(const std::string &dbusSource)
771{
772 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
773 {
774 return "None";
775 }
776 else if (dbusSource ==
777 "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
778 {
779 return "Hdd";
780 }
781 else if (dbusSource ==
Santosh Puranika71dc0b2019-05-23 20:10:49 +0530782 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530783 {
784 return "Cd";
785 }
786 else if (dbusSource ==
787 "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
788 {
789 return "Pxe";
790 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700791 else if (dbusSource ==
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700792 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700793 {
794 return "Usb";
795 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530796 else
797 {
798 return "";
799 }
800}
801
802/**
803 * @brief Traslates boot mode DBUS property value to redfish.
804 *
805 * @param[in] dbusMode The boot mode in DBUS speak.
806 *
807 * @return Returns as a string, the boot mode in Redfish terms. If translation
808 * cannot be done, returns an empty string.
809 */
810static std::string dbusToRfBootMode(const std::string &dbusMode)
811{
812 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
813 {
814 return "None";
815 }
816 else if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
817 {
818 return "Diags";
819 }
820 else if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
821 {
822 return "BiosSetup";
823 }
824 else
825 {
826 return "";
827 }
828}
829
830/**
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700831 * @brief Traslates boot source from Redfish to the DBus boot paths.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530832 *
833 * @param[in] rfSource The boot source in Redfish.
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700834 * @param[out] bootSource The DBus source
835 * @param[out] bootMode the DBus boot mode
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530836 *
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700837 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530838 */
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700839static int assignBootParameters(std::shared_ptr<AsyncResp> aResp,
840 const std::string &rfSource,
841 std::string &bootSource, std::string &bootMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530842{
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700843 // The caller has initialized the bootSource and bootMode to:
844 // bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
845 // bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
846 // Only modify the bootSource/bootMode variable needed to achieve the
847 // desired boot action.
848
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530849 if (rfSource == "None")
850 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700851 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530852 }
853 else if (rfSource == "Pxe")
854 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700855 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
856 }
857 else if (rfSource == "Hdd")
858 {
859 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
860 }
861 else if (rfSource == "Diags")
862 {
863 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
864 }
865 else if (rfSource == "Cd")
866 {
867 bootSource =
868 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
869 }
870 else if (rfSource == "BiosSetup")
871 {
872 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530873 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700874 else if (rfSource == "Usb")
875 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700876 bootSource =
877 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700878 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530879 else
880 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700881 BMCWEB_LOG_DEBUG << "Invalid property value for "
882 "BootSourceOverrideTarget: "
883 << bootSource;
884 messages::propertyValueNotInList(aResp->res, rfSource,
885 "BootSourceTargetOverride");
886 return -1;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530887 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700888 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530889}
890
891/**
892 * @brief Retrieves boot mode over DBUS and fills out the response
893 *
894 * @param[in] aResp Shared pointer for generating response message.
895 * @param[in] bootDbusObj The dbus object to query for boot properties.
896 *
897 * @return None.
898 */
899static void getBootMode(std::shared_ptr<AsyncResp> aResp,
900 std::string bootDbusObj)
901{
902 crow::connections::systemBus->async_method_call(
903 [aResp](const boost::system::error_code ec,
904 const std::variant<std::string> &bootMode) {
905 if (ec)
906 {
907 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
908 messages::internalError(aResp->res);
909 return;
910 }
911
912 const std::string *bootModeStr =
913 std::get_if<std::string>(&bootMode);
914
915 if (!bootModeStr)
916 {
917 messages::internalError(aResp->res);
918 return;
919 }
920
921 BMCWEB_LOG_DEBUG << "Boot mode: " << *bootModeStr;
922
923 // TODO (Santosh): Do we need to support override mode?
924 aResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = "Legacy";
925 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget@Redfish."
926 "AllowableValues"] = {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700927 "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530928
929 if (*bootModeStr !=
930 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
931 {
932 auto rfMode = dbusToRfBootMode(*bootModeStr);
933 if (!rfMode.empty())
934 {
935 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
936 rfMode;
937 }
938 }
939
940 // If the BootSourceOverrideTarget is still "None" at the end,
941 // reset the BootSourceOverrideEnabled to indicate that
942 // overrides are disabled
943 if (aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] ==
944 "None")
945 {
946 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
947 "Disabled";
948 }
949 },
950 "xyz.openbmc_project.Settings", bootDbusObj,
951 "org.freedesktop.DBus.Properties", "Get",
952 "xyz.openbmc_project.Control.Boot.Mode", "BootMode");
953}
954
955/**
956 * @brief Retrieves boot source over DBUS
957 *
958 * @param[in] aResp Shared pointer for generating response message.
959 * @param[in] oneTimeEnable Boolean to indicate boot properties are one-time.
960 *
961 * @return None.
962 */
963static void getBootSource(std::shared_ptr<AsyncResp> aResp, bool oneTimeEnabled)
964{
965 std::string bootDbusObj =
966 oneTimeEnabled ? "/xyz/openbmc_project/control/host0/boot/one_time"
967 : "/xyz/openbmc_project/control/host0/boot";
968
969 BMCWEB_LOG_DEBUG << "Is one time: " << oneTimeEnabled;
970 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
971 (oneTimeEnabled) ? "Once" : "Continuous";
972
973 crow::connections::systemBus->async_method_call(
974 [aResp, bootDbusObj](const boost::system::error_code ec,
975 const std::variant<std::string> &bootSource) {
976 if (ec)
977 {
978 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
979 messages::internalError(aResp->res);
980 return;
981 }
982
983 const std::string *bootSourceStr =
984 std::get_if<std::string>(&bootSource);
985
986 if (!bootSourceStr)
987 {
988 messages::internalError(aResp->res);
989 return;
990 }
991 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSourceStr;
992
993 auto rfSource = dbusToRfBootSource(*bootSourceStr);
994 if (!rfSource.empty())
995 {
996 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
997 rfSource;
998 }
999 },
1000 "xyz.openbmc_project.Settings", bootDbusObj,
1001 "org.freedesktop.DBus.Properties", "Get",
1002 "xyz.openbmc_project.Control.Boot.Source", "BootSource");
1003 getBootMode(std::move(aResp), std::move(bootDbusObj));
1004}
1005
1006/**
1007 * @brief Retrieves "One time" enabled setting over DBUS and calls function to
1008 * get boot source and boot mode.
1009 *
1010 * @param[in] aResp Shared pointer for generating response message.
1011 *
1012 * @return None.
1013 */
1014static void getBootProperties(std::shared_ptr<AsyncResp> aResp)
1015{
1016 BMCWEB_LOG_DEBUG << "Get boot information.";
1017
1018 crow::connections::systemBus->async_method_call(
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001019 [aResp](const boost::system::error_code ec,
1020 const sdbusplus::message::variant<bool> &oneTime) {
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301021 if (ec)
1022 {
1023 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
James Feist2a833c72019-07-19 10:17:13 -07001024 // not an error, don't have to have the interface
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301025 return;
1026 }
1027
1028 const bool *oneTimePtr = std::get_if<bool>(&oneTime);
1029
1030 if (!oneTimePtr)
1031 {
1032 messages::internalError(aResp->res);
1033 return;
1034 }
1035 getBootSource(aResp, *oneTimePtr);
1036 },
1037 "xyz.openbmc_project.Settings",
1038 "/xyz/openbmc_project/control/host0/boot/one_time",
1039 "org.freedesktop.DBus.Properties", "Get",
1040 "xyz.openbmc_project.Object.Enable", "Enabled");
1041}
1042
1043/**
1044 * @brief Sets boot properties into DBUS object(s).
1045 *
1046 * @param[in] aResp Shared pointer for generating response message.
1047 * @param[in] oneTimeEnabled Is "one-time" setting already enabled.
1048 * @param[in] bootSource The boot source to set.
1049 * @param[in] bootEnable The source override "enable" to set.
1050 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001051 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301052 */
1053static void setBootModeOrSource(std::shared_ptr<AsyncResp> aResp,
1054 bool oneTimeEnabled,
1055 std::optional<std::string> bootSource,
1056 std::optional<std::string> bootEnable)
1057{
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001058 std::string bootSourceStr =
1059 "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
1060 std::string bootModeStr =
1061 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301062 bool oneTimeSetting = oneTimeEnabled;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001063 bool useBootSource = true;
1064
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301065 // Validate incoming parameters
1066 if (bootEnable)
1067 {
1068 if (*bootEnable == "Once")
1069 {
1070 oneTimeSetting = true;
1071 }
1072 else if (*bootEnable == "Continuous")
1073 {
1074 oneTimeSetting = false;
1075 }
1076 else if (*bootEnable == "Disabled")
1077 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001078 BMCWEB_LOG_DEBUG << "Boot source override will be disabled";
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301079 oneTimeSetting = false;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001080 useBootSource = false;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301081 }
1082 else
1083 {
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301084 BMCWEB_LOG_DEBUG << "Unsupported value for "
1085 "BootSourceOverrideEnabled: "
1086 << *bootEnable;
1087 messages::propertyValueNotInList(aResp->res, *bootEnable,
1088 "BootSourceOverrideEnabled");
1089 return;
1090 }
1091 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301092
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001093 if (bootSource && useBootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301094 {
1095 // Source target specified
1096 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource;
1097 // Figure out which DBUS interface and property to use
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001098 if (assignBootParameters(aResp, *bootSource, bootSourceStr,
1099 bootModeStr))
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301100 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001101 BMCWEB_LOG_DEBUG
1102 << "Invalid property value for BootSourceOverrideTarget: "
1103 << *bootSource;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301104 messages::propertyValueNotInList(aResp->res, *bootSource,
1105 "BootSourceTargetOverride");
1106 return;
1107 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001108 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301109
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001110 // Act on validated parameters
1111 BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
1112 BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;
1113 const char *bootObj =
1114 oneTimeSetting ? "/xyz/openbmc_project/control/host0/boot/one_time"
1115 : "/xyz/openbmc_project/control/host0/boot";
1116
1117 crow::connections::systemBus->async_method_call(
1118 [aResp](const boost::system::error_code ec) {
1119 if (ec)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301120 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001121 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1122 messages::internalError(aResp->res);
1123 return;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301124 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001125 BMCWEB_LOG_DEBUG << "Boot source update done.";
1126 },
1127 "xyz.openbmc_project.Settings", bootObj,
1128 "org.freedesktop.DBus.Properties", "Set",
1129 "xyz.openbmc_project.Control.Boot.Source", "BootSource",
1130 std::variant<std::string>(bootSourceStr));
1131
1132 crow::connections::systemBus->async_method_call(
1133 [aResp](const boost::system::error_code ec) {
1134 if (ec)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301135 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001136 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1137 messages::internalError(aResp->res);
1138 return;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301139 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001140 BMCWEB_LOG_DEBUG << "Boot mode update done.";
1141 },
1142 "xyz.openbmc_project.Settings", bootObj,
1143 "org.freedesktop.DBus.Properties", "Set",
1144 "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
1145 std::variant<std::string>(bootModeStr));
1146
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301147 crow::connections::systemBus->async_method_call(
1148 [aResp{std::move(aResp)}](const boost::system::error_code ec) {
1149 if (ec)
1150 {
1151 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1152 messages::internalError(aResp->res);
1153 return;
1154 }
1155 BMCWEB_LOG_DEBUG << "Boot enable update done.";
1156 },
1157 "xyz.openbmc_project.Settings",
1158 "/xyz/openbmc_project/control/host0/boot/one_time",
1159 "org.freedesktop.DBus.Properties", "Set",
1160 "xyz.openbmc_project.Object.Enable", "Enabled",
1161 std::variant<bool>(oneTimeSetting));
1162}
1163
1164/**
1165 * @brief Retrieves "One time" enabled setting over DBUS and calls function to
1166 * set boot source/boot mode properties.
1167 *
1168 * @param[in] aResp Shared pointer for generating response message.
1169 * @param[in] bootSource The boot source from incoming RF request.
1170 * @param[in] bootEnable The boot override enable from incoming RF request.
1171 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001172 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301173 */
1174static void setBootProperties(std::shared_ptr<AsyncResp> aResp,
1175 std::optional<std::string> bootSource,
1176 std::optional<std::string> bootEnable)
1177{
1178 BMCWEB_LOG_DEBUG << "Set boot information.";
1179
1180 crow::connections::systemBus->async_method_call(
Johnathan Mantey265c1602019-08-08 11:02:51 -07001181 [aResp, bootSource{std::move(bootSource)},
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301182 bootEnable{std::move(bootEnable)}](
1183 const boost::system::error_code ec,
1184 const sdbusplus::message::variant<bool> &oneTime) {
1185 if (ec)
1186 {
1187 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1188 messages::internalError(aResp->res);
1189 return;
1190 }
1191
1192 const bool *oneTimePtr = std::get_if<bool>(&oneTime);
1193
1194 if (!oneTimePtr)
1195 {
1196 messages::internalError(aResp->res);
1197 return;
1198 }
1199
1200 BMCWEB_LOG_DEBUG << "Got one time: " << *oneTimePtr;
1201
1202 setBootModeOrSource(aResp, *oneTimePtr, std::move(bootSource),
1203 std::move(bootEnable));
1204 },
1205 "xyz.openbmc_project.Settings",
1206 "/xyz/openbmc_project/control/host0/boot/one_time",
1207 "org.freedesktop.DBus.Properties", "Get",
1208 "xyz.openbmc_project.Object.Enable", "Enabled");
1209}
1210
AppaRao Pulia6349912019-10-18 17:16:08 +05301211#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1212/**
1213 * @brief Retrieves provisioning status
1214 *
1215 * @param[in] aResp Shared pointer for completing asynchronous calls.
1216 *
1217 * @return None.
1218 */
1219void getProvisioningStatus(std::shared_ptr<AsyncResp> aResp)
1220{
1221 BMCWEB_LOG_DEBUG << "Get OEM information.";
1222 crow::connections::systemBus->async_method_call(
1223 [aResp](const boost::system::error_code ec,
1224 const std::vector<std::pair<std::string, VariantType>>
1225 &propertiesList) {
1226 if (ec)
1227 {
1228 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1229 messages::internalError(aResp->res);
1230 return;
1231 }
1232
1233 const bool *provState = nullptr;
1234 const bool *lockState = nullptr;
1235 for (const std::pair<std::string, VariantType> &property :
1236 propertiesList)
1237 {
1238 if (property.first == "UfmProvisioned")
1239 {
1240 provState = std::get_if<bool>(&property.second);
1241 }
1242 else if (property.first == "UfmLocked")
1243 {
1244 lockState = std::get_if<bool>(&property.second);
1245 }
1246 }
1247
1248 if ((provState == nullptr) || (lockState == nullptr))
1249 {
1250 BMCWEB_LOG_DEBUG << "Unable to get PFR attributes.";
1251 messages::internalError(aResp->res);
1252 return;
1253 }
1254
1255 nlohmann::json &oemPFR =
1256 aResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
1257 if (*provState == true)
1258 {
1259 if (*lockState == true)
1260 {
1261 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
1262 }
1263 else
1264 {
1265 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
1266 }
1267 }
1268 else
1269 {
1270 oemPFR["ProvisioningStatus"] = "NotProvisioned";
1271 }
1272 },
1273 "xyz.openbmc_project.PFR.Manager", "/xyz/openbmc_project/pfr",
1274 "org.freedesktop.DBus.Properties", "GetAll",
1275 "xyz.openbmc_project.PFR.Attributes");
1276}
1277#endif
1278
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301279/**
Yong Li51709ff2019-09-30 14:13:04 +08001280 * @brief Translates watchdog timeout action DBUS property value to redfish.
1281 *
1282 * @param[in] dbusAction The watchdog timeout action in D-BUS.
1283 *
1284 * @return Returns as a string, the timeout action in Redfish terms. If
1285 * translation cannot be done, returns an empty string.
1286 */
1287static std::string dbusToRfWatchdogAction(const std::string &dbusAction)
1288{
1289 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
1290 {
1291 return "None";
1292 }
1293 else if (dbusAction ==
1294 "xyz.openbmc_project.State.Watchdog.Action.HardReset")
1295 {
1296 return "ResetSystem";
1297 }
1298 else if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
1299 {
1300 return "PowerDown";
1301 }
1302 else if (dbusAction ==
1303 "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
1304 {
1305 return "PowerCycle";
1306 }
1307
1308 return "";
1309}
1310
1311/**
Yong Lic45f0082019-10-10 14:19:01 +08001312 *@brief Translates timeout action from Redfish to DBUS property value.
1313 *
1314 *@param[in] rfAction The timeout action in Redfish.
1315 *
1316 *@return Returns as a string, the time_out action as expected by DBUS.
1317 *If translation cannot be done, returns an empty string.
1318 */
1319
1320static std::string rfToDbusWDTTimeOutAct(const std::string &rfAction)
1321{
1322 if (rfAction == "None")
1323 {
1324 return "xyz.openbmc_project.State.Watchdog.Action.None";
1325 }
1326 else if (rfAction == "PowerCycle")
1327 {
1328 return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
1329 }
1330 else if (rfAction == "PowerDown")
1331 {
1332 return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
1333 }
1334 else if (rfAction == "ResetSystem")
1335 {
1336 return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
1337 }
1338
1339 return "";
1340}
1341
1342/**
Yong Li51709ff2019-09-30 14:13:04 +08001343 * @brief Retrieves host watchdog timer properties over DBUS
1344 *
1345 * @param[in] aResp Shared pointer for completing asynchronous calls.
1346 *
1347 * @return None.
1348 */
1349void getHostWatchdogTimer(std::shared_ptr<AsyncResp> aResp)
1350{
1351 BMCWEB_LOG_DEBUG << "Get host watchodg";
1352 crow::connections::systemBus->async_method_call(
1353 [aResp](const boost::system::error_code ec,
1354 PropertiesType &properties) {
1355 if (ec)
1356 {
1357 // watchdog service is stopped
1358 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1359 return;
1360 }
1361
1362 BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop.";
1363
1364 nlohmann::json &hostWatchdogTimer =
1365 aResp->res.jsonValue["HostWatchdogTimer"];
1366
1367 // watchdog service is running/enabled
1368 hostWatchdogTimer["Status"]["State"] = "Enabled";
1369
1370 for (const auto &property : properties)
1371 {
1372 BMCWEB_LOG_DEBUG << "prop=" << property.first;
1373 if (property.first == "Enabled")
1374 {
1375 const bool *state = std::get_if<bool>(&property.second);
1376
1377 if (!state)
1378 {
1379 messages::internalError(aResp->res);
1380 continue;
1381 }
1382
1383 hostWatchdogTimer["FunctionEnabled"] = *state;
1384 }
1385 else if (property.first == "ExpireAction")
1386 {
1387 const std::string *s =
1388 std::get_if<std::string>(&property.second);
1389 if (!s)
1390 {
1391 messages::internalError(aResp->res);
1392 continue;
1393 }
1394
1395 std::string action = dbusToRfWatchdogAction(*s);
1396 if (action.empty())
1397 {
1398 messages::internalError(aResp->res);
1399 continue;
1400 }
1401 hostWatchdogTimer["TimeoutAction"] = action;
1402 }
1403 }
1404 },
1405 "xyz.openbmc_project.Watchdog", "/xyz/openbmc_project/watchdog/host0",
1406 "org.freedesktop.DBus.Properties", "GetAll",
1407 "xyz.openbmc_project.State.Watchdog");
1408}
1409
1410/**
Yong Lic45f0082019-10-10 14:19:01 +08001411 * @brief Sets Host WatchDog Timer properties.
1412 *
1413 * @param[in] aResp Shared pointer for generating response message.
1414 * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming
1415 * RF request.
1416 * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
1417 *
1418 * @return None.
1419 */
1420static void setWDTProperties(std::shared_ptr<AsyncResp> aResp,
1421 const std::optional<bool> wdtEnable,
1422 const std::optional<std::string> &wdtTimeOutAction)
1423{
1424 BMCWEB_LOG_DEBUG << "Set host watchdog";
1425
1426 if (wdtTimeOutAction)
1427 {
1428 std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
1429 // check if TimeOut Action is Valid
1430 if (wdtTimeOutActStr.empty())
1431 {
1432 BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: "
1433 << *wdtTimeOutAction;
1434 messages::propertyValueNotInList(aResp->res, *wdtTimeOutAction,
1435 "TimeoutAction");
1436 return;
1437 }
1438
1439 crow::connections::systemBus->async_method_call(
1440 [aResp](const boost::system::error_code ec) {
1441 if (ec)
1442 {
1443 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1444 messages::internalError(aResp->res);
1445 return;
1446 }
1447 },
1448 "xyz.openbmc_project.Watchdog",
1449 "/xyz/openbmc_project/watchdog/host0",
1450 "org.freedesktop.DBus.Properties", "Set",
1451 "xyz.openbmc_project.State.Watchdog", "ExpireAction",
1452 std::variant<std::string>(wdtTimeOutActStr));
1453 }
1454
1455 if (wdtEnable)
1456 {
1457 crow::connections::systemBus->async_method_call(
1458 [aResp](const boost::system::error_code ec) {
1459 if (ec)
1460 {
1461 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1462 messages::internalError(aResp->res);
1463 return;
1464 }
1465 },
1466 "xyz.openbmc_project.Watchdog",
1467 "/xyz/openbmc_project/watchdog/host0",
1468 "org.freedesktop.DBus.Properties", "Set",
1469 "xyz.openbmc_project.State.Watchdog", "Enabled",
1470 std::variant<bool>(*wdtEnable));
1471 }
1472}
1473
1474/**
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001475 * SystemsCollection derived class for delivering ComputerSystems Collection
1476 * Schema
1477 */
Ed Tanous1abe55e2018-09-05 08:30:59 -07001478class SystemsCollection : public Node
1479{
1480 public:
1481 SystemsCollection(CrowApp &app) : Node(app, "/redfish/v1/Systems/")
1482 {
Ed Tanous1abe55e2018-09-05 08:30:59 -07001483 entityPrivileges = {
1484 {boost::beast::http::verb::get, {{"Login"}}},
1485 {boost::beast::http::verb::head, {{"Login"}}},
1486 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1487 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1488 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1489 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1490 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001491
Ed Tanous1abe55e2018-09-05 08:30:59 -07001492 private:
Ed Tanous1abe55e2018-09-05 08:30:59 -07001493 void doGet(crow::Response &res, const crow::Request &req,
1494 const std::vector<std::string> &params) override
1495 {
Ed Tanous0f74e642018-11-12 15:17:05 -08001496 res.jsonValue["@odata.type"] =
1497 "#ComputerSystemCollection.ComputerSystemCollection";
1498 res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
1499 res.jsonValue["@odata.context"] =
1500 "/redfish/v1/"
1501 "$metadata#ComputerSystemCollection.ComputerSystemCollection";
1502 res.jsonValue["Name"] = "Computer System Collection";
Ed Tanous029573d2019-02-01 10:57:49 -08001503 res.jsonValue["Members"] = {
1504 {{"@odata.id", "/redfish/v1/Systems/system"}}};
1505 res.jsonValue["Members@odata.count"] = 1;
1506 res.end();
Ed Tanous1abe55e2018-09-05 08:30:59 -07001507 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001508};
1509
1510/**
Ed Tanouscc340dd2018-08-29 13:43:38 -07001511 * SystemActionsReset class supports handle POST method for Reset action.
1512 * The class retrieves and sends data directly to D-Bus.
1513 */
1514class SystemActionsReset : public Node
1515{
1516 public:
1517 SystemActionsReset(CrowApp &app) :
Ed Tanous029573d2019-02-01 10:57:49 -08001518 Node(app, "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/")
Ed Tanouscc340dd2018-08-29 13:43:38 -07001519 {
1520 entityPrivileges = {
1521 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1522 }
1523
1524 private:
1525 /**
1526 * Function handles POST method request.
1527 * Analyzes POST body message before sends Reset request data to D-Bus.
1528 */
1529 void doPost(crow::Response &res, const crow::Request &req,
1530 const std::vector<std::string> &params) override
1531 {
Ed Tanous9712f8a2018-09-21 13:38:49 -07001532 auto asyncResp = std::make_shared<AsyncResp>(res);
1533
1534 std::string resetType;
1535 if (!json_util::readJson(req, res, "ResetType", resetType))
Ed Tanouscc340dd2018-08-29 13:43:38 -07001536 {
1537 return;
1538 }
1539
Jason M. Billsd22c8392019-06-03 13:59:03 -07001540 // Get the command and host vs. chassis
Ed Tanous9712f8a2018-09-21 13:38:49 -07001541 std::string command;
Jason M. Billsd22c8392019-06-03 13:59:03 -07001542 bool hostCommand;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001543 if (resetType == "On")
1544 {
1545 command = "xyz.openbmc_project.State.Host.Transition.On";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001546 hostCommand = true;
1547 }
1548 else if (resetType == "ForceOff")
1549 {
1550 command = "xyz.openbmc_project.State.Chassis.Transition.Off";
1551 hostCommand = false;
1552 }
1553 else if (resetType == "ForceOn")
1554 {
1555 command = "xyz.openbmc_project.State.Host.Transition.On";
1556 hostCommand = true;
1557 }
1558 else if (resetType == "ForceRestart")
1559 {
1560 command = "xyz.openbmc_project.State.Chassis.Transition.Reset";
1561 hostCommand = false;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001562 }
1563 else if (resetType == "GracefulShutdown")
1564 {
1565 command = "xyz.openbmc_project.State.Host.Transition.Off";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001566 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001567 }
1568 else if (resetType == "GracefulRestart")
1569 {
1570 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001571 hostCommand = true;
1572 }
1573 else if (resetType == "PowerCycle")
1574 {
1575 command = "xyz.openbmc_project.State.Chassis.Transition.PowerCycle";
1576 hostCommand = false;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001577 }
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001578 else if (resetType == "Nmi")
1579 {
1580 doNMI(asyncResp);
1581 return;
1582 }
Ed Tanous9712f8a2018-09-21 13:38:49 -07001583 else
1584 {
Jason M. Billsf12894f2018-10-09 12:45:45 -07001585 messages::actionParameterUnknown(res, "Reset", resetType);
Ed Tanous9712f8a2018-09-21 13:38:49 -07001586 return;
1587 }
1588
Jason M. Billsd22c8392019-06-03 13:59:03 -07001589 if (hostCommand)
1590 {
1591 crow::connections::systemBus->async_method_call(
1592 [asyncResp, resetType](const boost::system::error_code ec) {
1593 if (ec)
1594 {
1595 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1596 if (ec.value() == boost::asio::error::invalid_argument)
1597 {
1598 messages::actionParameterNotSupported(
1599 asyncResp->res, resetType, "Reset");
1600 }
1601 else
1602 {
1603 messages::internalError(asyncResp->res);
1604 }
1605 return;
1606 }
1607 messages::success(asyncResp->res);
1608 },
1609 "xyz.openbmc_project.State.Host",
1610 "/xyz/openbmc_project/state/host0",
1611 "org.freedesktop.DBus.Properties", "Set",
1612 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
1613 std::variant<std::string>{command});
1614 }
1615 else
1616 {
1617 crow::connections::systemBus->async_method_call(
1618 [asyncResp, resetType](const boost::system::error_code ec) {
1619 if (ec)
1620 {
1621 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1622 if (ec.value() == boost::asio::error::invalid_argument)
1623 {
1624 messages::actionParameterNotSupported(
1625 asyncResp->res, resetType, "Reset");
1626 }
1627 else
1628 {
1629 messages::internalError(asyncResp->res);
1630 }
1631 return;
1632 }
1633 messages::success(asyncResp->res);
1634 },
1635 "xyz.openbmc_project.State.Chassis",
1636 "/xyz/openbmc_project/state/chassis0",
1637 "org.freedesktop.DBus.Properties", "Set",
1638 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
1639 std::variant<std::string>{command});
1640 }
Ed Tanouscc340dd2018-08-29 13:43:38 -07001641 }
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001642 /**
1643 * Function transceives data with dbus directly.
1644 */
1645 void doNMI(const std::shared_ptr<AsyncResp> &asyncResp)
1646 {
1647 constexpr char const *serviceName =
1648 "xyz.openbmc_project.Control.Host.NMI";
1649 constexpr char const *objectPath =
1650 "/xyz/openbmc_project/control/host0/nmi";
1651 constexpr char const *interfaceName =
1652 "xyz.openbmc_project.Control.Host.NMI";
1653 constexpr char const *method = "NMI";
1654
1655 crow::connections::systemBus->async_method_call(
1656 [asyncResp](const boost::system::error_code ec) {
1657 if (ec)
1658 {
1659 BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
1660 messages::internalError(asyncResp->res);
1661 return;
1662 }
1663 messages::success(asyncResp->res);
1664 },
1665 serviceName, objectPath, interfaceName, method);
1666 }
Ed Tanouscc340dd2018-08-29 13:43:38 -07001667};
1668
1669/**
Ed Tanous66173382018-08-15 18:20:59 -07001670 * Systems derived class for delivering Computer Systems Schema.
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001671 */
Ed Tanous1abe55e2018-09-05 08:30:59 -07001672class Systems : public Node
1673{
1674 public:
1675 /*
1676 * Default Constructor
1677 */
Ed Tanous029573d2019-02-01 10:57:49 -08001678 Systems(CrowApp &app) : Node(app, "/redfish/v1/Systems/system/")
Ed Tanous1abe55e2018-09-05 08:30:59 -07001679 {
Ed Tanous1abe55e2018-09-05 08:30:59 -07001680 entityPrivileges = {
1681 {boost::beast::http::verb::get, {{"Login"}}},
1682 {boost::beast::http::verb::head, {{"Login"}}},
1683 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1684 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1685 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1686 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001687 }
1688
Ed Tanous1abe55e2018-09-05 08:30:59 -07001689 private:
Ed Tanous1abe55e2018-09-05 08:30:59 -07001690 /**
1691 * Functions triggers appropriate requests on DBus
1692 */
1693 void doGet(crow::Response &res, const crow::Request &req,
1694 const std::vector<std::string> &params) override
1695 {
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301696 res.jsonValue["@odata.type"] = "#ComputerSystem.v1_6_0.ComputerSystem";
Ed Tanous0f74e642018-11-12 15:17:05 -08001697 res.jsonValue["@odata.context"] =
1698 "/redfish/v1/$metadata#ComputerSystem.ComputerSystem";
Ed Tanous029573d2019-02-01 10:57:49 -08001699 res.jsonValue["Name"] = "Computer System";
1700 res.jsonValue["Id"] = "system";
Ed Tanous0f74e642018-11-12 15:17:05 -08001701 res.jsonValue["SystemType"] = "Physical";
1702 res.jsonValue["Description"] = "Computer System";
Ed Tanous0f74e642018-11-12 15:17:05 -08001703 res.jsonValue["ProcessorSummary"]["Count"] = 0;
1704 res.jsonValue["ProcessorSummary"]["Status"]["State"] = "Disabled";
Cheng C Yang5fd7ba62019-11-28 15:58:08 +08001705 res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = uint64_t(0);
Ed Tanous0f74e642018-11-12 15:17:05 -08001706 res.jsonValue["MemorySummary"]["Status"]["State"] = "Disabled";
Ed Tanous029573d2019-02-01 10:57:49 -08001707 res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
Ed Tanous04a258f2018-10-15 08:00:41 -07001708
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001709 res.jsonValue["Processors"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001710 {"@odata.id", "/redfish/v1/Systems/system/Processors"}};
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001711 res.jsonValue["Memory"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001712 {"@odata.id", "/redfish/v1/Systems/system/Memory"}};
Nikhil Potadea25aecc2019-08-23 16:35:26 -07001713 res.jsonValue["Storage"] = {
1714 {"@odata.id", "/redfish/v1/Systems/system/Storage"}};
Ed Tanous029573d2019-02-01 10:57:49 -08001715
Ed Tanouscc340dd2018-08-29 13:43:38 -07001716 // TODO Need to support ForceRestart.
1717 res.jsonValue["Actions"]["#ComputerSystem.Reset"] = {
1718 {"target",
Ed Tanous029573d2019-02-01 10:57:49 -08001719 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"},
Ed Tanouscc340dd2018-08-29 13:43:38 -07001720 {"ResetType@Redfish.AllowableValues",
Jason M. Billsd22c8392019-06-03 13:59:03 -07001721 {"On", "ForceOff", "ForceOn", "ForceRestart", "GracefulRestart",
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001722 "GracefulShutdown", "PowerCycle", "Nmi"}}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001723
Jason M. Billsc4bf6372018-11-05 13:48:27 -08001724 res.jsonValue["LogServices"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001725 {"@odata.id", "/redfish/v1/Systems/system/LogServices"}};
Jason M. Billsc4bf6372018-11-05 13:48:27 -08001726
Carol Wangd82a3ac2019-11-21 13:56:38 +08001727 res.jsonValue["Bios"] = {
1728 {"@odata.id", "/redfish/v1/Systems/system/Bios"}};
1729
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001730 res.jsonValue["Links"]["ManagedBy"] = {
1731 {{"@odata.id", "/redfish/v1/Managers/bmc"}}};
1732
1733 res.jsonValue["Status"] = {
1734 {"Health", "OK"},
1735 {"State", "Enabled"},
1736 };
Ed Tanousa0803ef2018-08-29 13:29:23 -07001737 auto asyncResp = std::make_shared<AsyncResp>(res);
Ed Tanous1abe55e2018-09-05 08:30:59 -07001738
James Feiste284a7c2019-11-20 16:20:23 -08001739 constexpr const std::array<const char *, 4> inventoryForSystems = {
James Feistb49ac872019-05-21 15:12:01 -07001740 "xyz.openbmc_project.Inventory.Item.Dimm",
James Feist2ad9c2f2019-10-29 16:26:48 -07001741 "xyz.openbmc_project.Inventory.Item.Cpu",
James Feiste284a7c2019-11-20 16:20:23 -08001742 "xyz.openbmc_project.Inventory.Item.Drive",
1743 "xyz.openbmc_project.Inventory.Item.StorageController"};
James Feistb49ac872019-05-21 15:12:01 -07001744
1745 auto health = std::make_shared<HealthPopulate>(asyncResp);
1746 crow::connections::systemBus->async_method_call(
1747 [health](const boost::system::error_code ec,
1748 std::vector<std::string> &resp) {
1749 if (ec)
1750 {
1751 // no inventory
1752 return;
1753 }
1754
1755 health->inventory = std::move(resp);
1756 },
1757 "xyz.openbmc_project.ObjectMapper",
1758 "/xyz/openbmc_project/object_mapper",
1759 "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", "/",
1760 int32_t(0), inventoryForSystems);
1761
1762 health->populate();
1763
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001764 getMainChassisId(asyncResp, [](const std::string &chassisId,
1765 std::shared_ptr<AsyncResp> aRsp) {
1766 aRsp->res.jsonValue["Links"]["Chassis"] = {
1767 {{"@odata.id", "/redfish/v1/Chassis/" + chassisId}}};
1768 });
AppaRao Pulia3002222019-11-12 21:32:59 +05301769
1770 getIndicatorLedState(asyncResp);
James Feist5bc2dc82019-10-22 14:33:16 -07001771 getComputerSystem(asyncResp, health);
Ed Tanous6c34de42018-08-29 13:37:36 -07001772 getHostState(asyncResp);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301773 getBootProperties(asyncResp);
Jason M. Billsadbe1922019-10-14 15:44:35 -07001774 getPCIeDeviceList(asyncResp, "PCIeDevices");
Yong Li51709ff2019-09-30 14:13:04 +08001775 getHostWatchdogTimer(asyncResp);
AppaRao Pulia6349912019-10-18 17:16:08 +05301776#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1777 getProvisioningStatus(asyncResp);
1778#endif
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001779 }
1780
Ed Tanous1abe55e2018-09-05 08:30:59 -07001781 void doPatch(crow::Response &res, const crow::Request &req,
1782 const std::vector<std::string> &params) override
1783 {
Santosh Puranikcde19e52019-02-20 00:10:56 +05301784 std::optional<std::string> indicatorLed;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301785 std::optional<nlohmann::json> bootProps;
Yong Lic45f0082019-10-10 14:19:01 +08001786 std::optional<nlohmann::json> wdtTimerProps;
Santosh Puranik41352c22019-07-03 05:35:49 -05001787 auto asyncResp = std::make_shared<AsyncResp>(res);
1788
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001789 if (!json_util::readJson(req, res, "IndicatorLED", indicatorLed, "Boot",
Yong Lic45f0082019-10-10 14:19:01 +08001790 bootProps, "WatchdogTimer", wdtTimerProps))
Ed Tanous66173382018-08-15 18:20:59 -07001791 {
Ed Tanous9712f8a2018-09-21 13:38:49 -07001792 return;
1793 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301794
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001795 res.result(boost::beast::http::status::no_content);
Yong Lic45f0082019-10-10 14:19:01 +08001796
1797 if (wdtTimerProps)
1798 {
1799 std::optional<bool> wdtEnable;
1800 std::optional<std::string> wdtTimeOutAction;
1801
1802 if (!json_util::readJson(*wdtTimerProps, asyncResp->res,
1803 "FunctionEnabled", wdtEnable,
1804 "TimeoutAction", wdtTimeOutAction))
1805 {
1806 return;
1807 }
1808 setWDTProperties(asyncResp, std::move(wdtEnable),
1809 std::move(wdtTimeOutAction));
1810 }
1811
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301812 if (bootProps)
1813 {
1814 std::optional<std::string> bootSource;
1815 std::optional<std::string> bootEnable;
1816
1817 if (!json_util::readJson(*bootProps, asyncResp->res,
1818 "BootSourceOverrideTarget", bootSource,
1819 "BootSourceOverrideEnabled", bootEnable))
1820 {
1821 return;
1822 }
1823 setBootProperties(asyncResp, std::move(bootSource),
1824 std::move(bootEnable));
1825 }
Johnathan Mantey265c1602019-08-08 11:02:51 -07001826
Ed Tanous9712f8a2018-09-21 13:38:49 -07001827 if (indicatorLed)
1828 {
AppaRao Pulia3002222019-11-12 21:32:59 +05301829 setIndicatorLedState(asyncResp, std::move(*indicatorLed));
Ed Tanous1abe55e2018-09-05 08:30:59 -07001830 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001831 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001832};
Ed Tanous1abe55e2018-09-05 08:30:59 -07001833} // namespace redfish