blob: 93eb40354faca5f261adf29942bff8f0da4960ce [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
85 nlohmann::json &procCount =
86 aResp->res.jsonValue["ProcessorSummary"]["Count"];
87 if (*isCpuPresent == true)
88 {
89 procCount = procCount.get<int>() + 1;
90 }
91 aResp->res.jsonValue["ProcessorSummary"]["Count"] = procCount;
92}
93
94/*
95 * @brief Update "ProcessorSummary" "Status" "State" based on
96 * CPU Functional State
97 *
98 * @param[in] aResp Shared pointer for completing asynchronous calls
99 * @param[in] cpuFunctionalState is CPU functional true/false
100 *
101 * @return None.
102 */
103void modifyCpuFunctionalState(std::shared_ptr<AsyncResp> aResp,
104 const std::variant<bool> &cpuFunctionalState)
105{
106 const bool *isCpuFunctional = std::get_if<bool>(&cpuFunctionalState);
107
108 if (isCpuFunctional == nullptr)
109 {
110 messages::internalError(aResp->res);
111 return;
112 }
Gunnar Mills698654b2019-10-16 13:17:37 -0500113 BMCWEB_LOG_DEBUG << "Cpu Functional: " << *isCpuFunctional;
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500114
115 nlohmann::json &prevProcState =
116 aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"];
117
118 // Set it as Enabled if atleast one CPU is functional
119 // Update STATE only if previous State was Non_Functional and current CPU is
120 // Functional.
121 if (prevProcState == "Disabled")
122 {
123 if (*isCpuFunctional == true)
124 {
125 aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
126 "Enabled";
127 }
128 }
129}
130
131/*
Ed Tanous6c34de42018-08-29 13:37:36 -0700132 * @brief Retrieves computer system properties over dbus
133 *
134 * @param[in] aResp Shared pointer for completing asynchronous calls
135 * @param[in] name Computer system name from request
136 *
137 * @return None.
138 */
James Feist5bc2dc82019-10-22 14:33:16 -0700139void getComputerSystem(std::shared_ptr<AsyncResp> aResp,
140 std::shared_ptr<HealthPopulate> systemHealth)
Ed Tanous6c34de42018-08-29 13:37:36 -0700141{
Ed Tanous6c34de42018-08-29 13:37:36 -0700142 BMCWEB_LOG_DEBUG << "Get available system components.";
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500143
Ed Tanous6c34de42018-08-29 13:37:36 -0700144 crow::connections::systemBus->async_method_call(
James Feist5bc2dc82019-10-22 14:33:16 -0700145 [aResp, systemHealth](
Ed Tanous6c34de42018-08-29 13:37:36 -0700146 const boost::system::error_code ec,
147 const std::vector<std::pair<
148 std::string,
149 std::vector<std::pair<std::string, std::vector<std::string>>>>>
150 &subtree) {
151 if (ec)
152 {
153 BMCWEB_LOG_DEBUG << "DBUS response error";
Jason M. Billsf12894f2018-10-09 12:45:45 -0700154 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700155 return;
156 }
Ed Tanous6c34de42018-08-29 13:37:36 -0700157 // Iterate over all retrieved ObjectPaths.
158 for (const std::pair<std::string,
159 std::vector<std::pair<
160 std::string, std::vector<std::string>>>>
161 &object : subtree)
162 {
163 const std::string &path = object.first;
164 BMCWEB_LOG_DEBUG << "Got path: " << path;
165 const std::vector<
166 std::pair<std::string, std::vector<std::string>>>
167 &connectionNames = object.second;
168 if (connectionNames.size() < 1)
169 {
170 continue;
171 }
Ed Tanous029573d2019-02-01 10:57:49 -0800172
James Feist5bc2dc82019-10-22 14:33:16 -0700173 auto memoryHealth = std::make_shared<HealthPopulate>(
174 aResp, aResp->res.jsonValue["MemorySummary"]["Status"]);
175
176 auto cpuHealth = std::make_shared<HealthPopulate>(
177 aResp, aResp->res.jsonValue["ProcessorSummary"]["Status"]);
178
179 systemHealth->children.emplace_back(memoryHealth);
180 systemHealth->children.emplace_back(cpuHealth);
181
Ed Tanous029573d2019-02-01 10:57:49 -0800182 // This is not system, so check if it's cpu, dimm, UUID or
183 // BiosVer
184 for (const auto &connection : connectionNames)
Ed Tanous6c34de42018-08-29 13:37:36 -0700185 {
Ed Tanous029573d2019-02-01 10:57:49 -0800186 for (const auto &interfaceName : connection.second)
Ed Tanous6c34de42018-08-29 13:37:36 -0700187 {
Ed Tanous029573d2019-02-01 10:57:49 -0800188 if (interfaceName ==
189 "xyz.openbmc_project.Inventory.Item.Dimm")
Ed Tanous6c34de42018-08-29 13:37:36 -0700190 {
Ed Tanous029573d2019-02-01 10:57:49 -0800191 BMCWEB_LOG_DEBUG
192 << "Found Dimm, now get its properties.";
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500193
Ed Tanous029573d2019-02-01 10:57:49 -0800194 crow::connections::systemBus->async_method_call(
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500195 [aResp, service{connection.first},
196 path(std::move(path))](
197 const boost::system::error_code ec,
198 const std::vector<
199 std::pair<std::string, VariantType>>
200 &properties) {
Ed Tanous029573d2019-02-01 10:57:49 -0800201 if (ec)
202 {
203 BMCWEB_LOG_ERROR
204 << "DBUS response error " << ec;
205 messages::internalError(aResp->res);
206 return;
207 }
208 BMCWEB_LOG_DEBUG << "Got "
209 << properties.size()
Gunnar Mills698654b2019-10-16 13:17:37 -0500210 << " Dimm properties.";
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500211
212 if (properties.size() > 0)
Ed Tanous029573d2019-02-01 10:57:49 -0800213 {
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500214 for (const std::pair<std::string,
215 VariantType>
216 &property : properties)
Ed Tanous6c34de42018-08-29 13:37:36 -0700217 {
Cheng C Yang5fd7ba62019-11-28 15:58:08 +0800218 if (property.first !=
219 "MemorySizeInKB")
Ed Tanous6c34de42018-08-29 13:37:36 -0700220 {
Cheng C Yang5fd7ba62019-11-28 15:58:08 +0800221 continue;
Ed Tanous6c34de42018-08-29 13:37:36 -0700222 }
Cheng C Yang5fd7ba62019-11-28 15:58:08 +0800223 const uint32_t *value =
224 sdbusplus::message::variant_ns::
225 get_if<uint32_t>(
226 &property.second);
227 if (value == nullptr)
228 {
229 BMCWEB_LOG_DEBUG
230 << "Find incorrect type of "
231 "MemorySize";
232 continue;
233 }
234 nlohmann::json &totalMemory =
235 aResp->res
236 .jsonValue["MemorySummar"
237 "y"]
238 ["TotalSystemMe"
239 "moryGiB"];
240 uint64_t *preValue =
241 totalMemory
242 .get_ptr<uint64_t *>();
243 if (preValue == nullptr)
244 {
245 continue;
246 }
247 aResp->res
248 .jsonValue["MemorySummary"]
249 ["TotalSystemMemoryGi"
250 "B"] =
251 *value / (1024 * 1024) +
252 *preValue;
253 aResp->res
254 .jsonValue["MemorySummary"]
255 ["Status"]["State"] =
256 "Enabled";
Ed Tanous6c34de42018-08-29 13:37:36 -0700257 }
Ed Tanous029573d2019-02-01 10:57:49 -0800258 }
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500259 else
260 {
261 auto getDimmProperties =
262 [aResp](
263 const boost::system::error_code
264 ec,
265 const std::variant<bool>
266 &dimmState) {
267 if (ec)
268 {
269 BMCWEB_LOG_ERROR
270 << "DBUS response "
271 "error "
272 << ec;
273 return;
274 }
275 updateDimmProperties(aResp,
276 dimmState);
277 };
278 crow::connections::systemBus
279 ->async_method_call(
280 std::move(getDimmProperties),
281 service, path,
282 "org.freedesktop.DBus."
283 "Properties",
284 "Get",
285 "xyz.openbmc_project.State."
286 "Decorator.OperationalStatus",
287 "Functional");
288 }
Ed Tanous029573d2019-02-01 10:57:49 -0800289 },
290 connection.first, path,
291 "org.freedesktop.DBus.Properties", "GetAll",
292 "xyz.openbmc_project.Inventory.Item.Dimm");
James Feist5bc2dc82019-10-22 14:33:16 -0700293
294 memoryHealth->inventory.emplace_back(path);
Ed Tanous029573d2019-02-01 10:57:49 -0800295 }
296 else if (interfaceName ==
297 "xyz.openbmc_project.Inventory.Item.Cpu")
298 {
299 BMCWEB_LOG_DEBUG
300 << "Found Cpu, now get its properties.";
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500301
Ed Tanous029573d2019-02-01 10:57:49 -0800302 crow::connections::systemBus->async_method_call(
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500303 [aResp, service{connection.first},
304 path(std::move(path))](
305 const boost::system::error_code ec,
306 const std::vector<
307 std::pair<std::string, VariantType>>
308 &properties) {
Ed Tanous029573d2019-02-01 10:57:49 -0800309 if (ec)
310 {
311 BMCWEB_LOG_ERROR
312 << "DBUS response error " << ec;
313 messages::internalError(aResp->res);
314 return;
315 }
316 BMCWEB_LOG_DEBUG << "Got "
317 << properties.size()
Gunnar Mills698654b2019-10-16 13:17:37 -0500318 << " Cpu properties.";
Ed Tanous04a258f2018-10-15 08:00:41 -0700319
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500320 if (properties.size() > 0)
321 {
322 for (const auto &property : properties)
323 {
324 if (property.first ==
325 "ProcessorFamily")
326 {
327 const std::string *value =
328 sdbusplus::message::
329 variant_ns::get_if<
330 std::string>(
331 &property.second);
332 if (value != nullptr)
333 {
334 nlohmann::json
335 &procSummary =
336 aResp->res.jsonValue
337 ["ProcessorSumm"
338 "ary"];
339 nlohmann::json &procCount =
340 procSummary["Count"];
341 procCount =
342 procCount.get<int>() +
343 1;
344 procSummary["Status"]
345 ["State"] =
346 "Enabled";
347 procSummary["Model"] =
348 *value;
349 }
Ed Tanous6c34de42018-08-29 13:37:36 -0700350 }
351 }
Ed Tanous029573d2019-02-01 10:57:49 -0800352 }
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500353 else
354 {
355 auto getCpuPresenceState =
356 [aResp](
357 const boost::system::error_code
358 ec,
359 const std::variant<bool>
360 &cpuPresenceCheck) {
361 if (ec)
362 {
363 BMCWEB_LOG_ERROR
364 << "DBUS response "
365 "error "
366 << ec;
367 return;
368 }
369 modifyCpuPresenceState(
370 aResp, cpuPresenceCheck);
371 };
372
373 auto getCpuFunctionalState =
374 [aResp](
375 const boost::system::error_code
376 ec,
377 const std::variant<bool>
378 &cpuFunctionalCheck) {
379 if (ec)
380 {
381 BMCWEB_LOG_ERROR
382 << "DBUS response "
383 "error "
384 << ec;
385 return;
386 }
387 modifyCpuFunctionalState(
388 aResp, cpuFunctionalCheck);
389 };
390 // Get the Presence of CPU
391 crow::connections::systemBus
392 ->async_method_call(
393 std::move(getCpuPresenceState),
394 service, path,
395 "org.freedesktop.DBus."
396 "Properties",
397 "Get",
398 "xyz.openbmc_project.Inventory."
399 "Item",
400 "Present");
401
402 // Get the Functional State
403 crow::connections::systemBus
404 ->async_method_call(
405 std::move(
406 getCpuFunctionalState),
407 service, path,
408 "org.freedesktop.DBus."
409 "Properties",
410 "Get",
411 "xyz.openbmc_project.State."
412 "Decorator."
413 "OperationalStatus",
414 "Functional");
415
416 // Get the MODEL from
417 // xyz.openbmc_project.Inventory.Decorator.Asset
418 // support it later as Model is Empty
419 // currently.
420 }
Ed Tanous029573d2019-02-01 10:57:49 -0800421 },
422 connection.first, path,
423 "org.freedesktop.DBus.Properties", "GetAll",
424 "xyz.openbmc_project.Inventory.Item.Cpu");
James Feist5bc2dc82019-10-22 14:33:16 -0700425
426 cpuHealth->inventory.emplace_back(path);
Ed Tanous029573d2019-02-01 10:57:49 -0800427 }
428 else if (interfaceName ==
429 "xyz.openbmc_project.Common.UUID")
430 {
431 BMCWEB_LOG_DEBUG
432 << "Found UUID, now get its properties.";
433 crow::connections::systemBus->async_method_call(
434 [aResp](const boost::system::error_code ec,
Ed Tanous6c34de42018-08-29 13:37:36 -0700435 const std::vector<
436 std::pair<std::string, VariantType>>
437 &properties) {
Ed Tanous029573d2019-02-01 10:57:49 -0800438 if (ec)
439 {
440 BMCWEB_LOG_DEBUG
441 << "DBUS response error " << ec;
442 messages::internalError(aResp->res);
443 return;
444 }
445 BMCWEB_LOG_DEBUG << "Got "
446 << properties.size()
Gunnar Mills698654b2019-10-16 13:17:37 -0500447 << " UUID properties.";
Ed Tanous029573d2019-02-01 10:57:49 -0800448 for (const std::pair<std::string,
449 VariantType>
450 &property : properties)
451 {
Ed Tanous029573d2019-02-01 10:57:49 -0800452 if (property.first == "UUID")
453 {
454 const std::string *value =
455 sdbusplus::message::variant_ns::
456 get_if<std::string>(
457 &property.second);
Ed Tanous04a258f2018-10-15 08:00:41 -0700458
Ed Tanous029573d2019-02-01 10:57:49 -0800459 if (value != nullptr)
460 {
461 std::string valueStr = *value;
462 if (valueStr.size() == 32)
Ed Tanous6c34de42018-08-29 13:37:36 -0700463 {
Ed Tanous029573d2019-02-01 10:57:49 -0800464 valueStr.insert(8, 1, '-');
465 valueStr.insert(13, 1, '-');
466 valueStr.insert(18, 1, '-');
467 valueStr.insert(23, 1, '-');
Ed Tanous6c34de42018-08-29 13:37:36 -0700468 }
Ed Tanous029573d2019-02-01 10:57:49 -0800469 BMCWEB_LOG_DEBUG << "UUID = "
470 << valueStr;
471 aResp->res.jsonValue["UUID"] =
472 valueStr;
Ed Tanous6c34de42018-08-29 13:37:36 -0700473 }
474 }
Ed Tanous029573d2019-02-01 10:57:49 -0800475 }
476 },
477 connection.first, path,
478 "org.freedesktop.DBus.Properties", "GetAll",
479 "xyz.openbmc_project.Common.UUID");
480 }
481 else if (interfaceName ==
482 "xyz.openbmc_project.Inventory.Item.System")
483 {
484 crow::connections::systemBus->async_method_call(
485 [aResp](const boost::system::error_code ec,
486 const std::vector<
487 std::pair<std::string, VariantType>>
488 &propertiesList) {
489 if (ec)
490 {
James Feiste4a4b9a2019-06-20 14:08:07 -0700491 // doesn't have to include this
492 // interface
Ed Tanous029573d2019-02-01 10:57:49 -0800493 return;
494 }
Gunnar Mills698654b2019-10-16 13:17:37 -0500495 BMCWEB_LOG_DEBUG
496 << "Got " << propertiesList.size()
497 << " properties for system";
Ed Tanous029573d2019-02-01 10:57:49 -0800498 for (const std::pair<std::string,
499 VariantType>
500 &property : propertiesList)
501 {
beccabroekfc5afcf2019-03-05 14:35:15 -0600502 const std::string &propertyName =
503 property.first;
504 if ((propertyName == "PartNumber") ||
505 (propertyName == "SerialNumber") ||
506 (propertyName == "Manufacturer") ||
507 (propertyName == "Model"))
Ed Tanous029573d2019-02-01 10:57:49 -0800508 {
beccabroekfc5afcf2019-03-05 14:35:15 -0600509 const std::string *value =
510 std::get_if<std::string>(
511 &property.second);
512 if (value != nullptr)
513 {
514 aResp->res
515 .jsonValue[propertyName] =
516 *value;
517 }
Ed Tanous029573d2019-02-01 10:57:49 -0800518 }
519 }
520 aResp->res.jsonValue["Name"] = "system";
521 aResp->res.jsonValue["Id"] =
522 aResp->res.jsonValue["SerialNumber"];
Andrew Geisslercb7e1e72019-02-19 13:05:38 -0600523 // Grab the bios version
524 fw_util::getActiveFwVersion(
525 aResp, fw_util::biosPurpose,
526 "BiosVersion");
Ed Tanous029573d2019-02-01 10:57:49 -0800527 },
528 connection.first, path,
529 "org.freedesktop.DBus.Properties", "GetAll",
530 "xyz.openbmc_project.Inventory.Decorator."
531 "Asset");
James Feiste4a4b9a2019-06-20 14:08:07 -0700532
533 crow::connections::systemBus->async_method_call(
534 [aResp](
535 const boost::system::error_code ec,
536 const std::variant<std::string> &property) {
537 if (ec)
538 {
539 // doesn't have to include this
540 // interface
541 return;
542 }
543
544 const std::string *value =
545 std::get_if<std::string>(&property);
546 if (value != nullptr)
547 {
548 aResp->res.jsonValue["AssetTag"] =
549 *value;
550 }
551 },
552 connection.first, path,
553 "org.freedesktop.DBus.Properties", "Get",
554 "xyz.openbmc_project.Inventory.Decorator."
555 "AssetTag",
556 "AssetTag");
Ed Tanous6c34de42018-08-29 13:37:36 -0700557 }
558 }
559 }
560 }
Ed Tanous6c34de42018-08-29 13:37:36 -0700561 },
562 "xyz.openbmc_project.ObjectMapper",
563 "/xyz/openbmc_project/object_mapper",
564 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
Ed Tanous66173382018-08-15 18:20:59 -0700565 "/xyz/openbmc_project/inventory", int32_t(0),
566 std::array<const char *, 5>{
567 "xyz.openbmc_project.Inventory.Decorator.Asset",
568 "xyz.openbmc_project.Inventory.Item.Cpu",
569 "xyz.openbmc_project.Inventory.Item.Dimm",
570 "xyz.openbmc_project.Inventory.Item.System",
571 "xyz.openbmc_project.Common.UUID",
572 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700573}
574
575/**
576 * @brief Retrieves identify led group properties over dbus
577 *
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530578 * @param[in] aResp Shared pointer for generating response message.
Ed Tanous6c34de42018-08-29 13:37:36 -0700579 *
580 * @return None.
581 */
AppaRao Pulia3002222019-11-12 21:32:59 +0530582void getIndicatorLedState(std::shared_ptr<AsyncResp> aResp)
Ed Tanous6c34de42018-08-29 13:37:36 -0700583{
584 BMCWEB_LOG_DEBUG << "Get led groups";
585 crow::connections::systemBus->async_method_call(
AppaRao Pulia3002222019-11-12 21:32:59 +0530586 [aResp](const boost::system::error_code ec,
587 const std::variant<bool> asserted) {
AppaRao Pulif847a192019-11-15 14:57:44 +0530588 // Some systems may not have enclosure_identify_blink object so
589 // proceed to get enclosure_identify state.
590 if (!ec)
Ed Tanous6c34de42018-08-29 13:37:36 -0700591 {
AppaRao Pulif847a192019-11-15 14:57:44 +0530592 const bool *blinking = std::get_if<bool>(&asserted);
593 if (!blinking)
594 {
595 BMCWEB_LOG_DEBUG << "Get identity blinking LED failed";
596 messages::internalError(aResp->res);
597 return;
598 }
599 // Blinking ON, no need to check enclosure_identify assert.
600 if (*blinking)
601 {
602 aResp->res.jsonValue["IndicatorLED"] = "Blinking";
603 return;
604 }
AppaRao Pulia3002222019-11-12 21:32:59 +0530605 }
606 crow::connections::systemBus->async_method_call(
607 [aResp](const boost::system::error_code ec,
608 const std::variant<bool> asserted) {
AppaRao Pulif847a192019-11-15 14:57:44 +0530609 if (!ec)
Ed Tanous6c34de42018-08-29 13:37:36 -0700610 {
AppaRao Pulif847a192019-11-15 14:57:44 +0530611 const bool *ledOn = std::get_if<bool>(&asserted);
612 if (!ledOn)
613 {
614 BMCWEB_LOG_DEBUG
615 << "Get enclosure identity led failed";
616 messages::internalError(aResp->res);
617 return;
618 }
AppaRao Pulia3002222019-11-12 21:32:59 +0530619
AppaRao Pulif847a192019-11-15 14:57:44 +0530620 if (*ledOn)
621 {
622 aResp->res.jsonValue["IndicatorLED"] = "Lit";
623 }
624 else
625 {
626 aResp->res.jsonValue["IndicatorLED"] = "Off";
627 }
AppaRao Pulia3002222019-11-12 21:32:59 +0530628 }
629 return;
630 },
631 "xyz.openbmc_project.LED.GroupManager",
632 "/xyz/openbmc_project/led/groups/enclosure_identify",
633 "org.freedesktop.DBus.Properties", "Get",
634 "xyz.openbmc_project.Led.Group", "Asserted");
635 },
636 "xyz.openbmc_project.LED.GroupManager",
637 "/xyz/openbmc_project/led/groups/enclosure_identify_blink",
638 "org.freedesktop.DBus.Properties", "Get",
639 "xyz.openbmc_project.Led.Group", "Asserted");
640}
641/**
642 * @brief Sets identify led group properties
643 *
644 * @param[in] aResp Shared pointer for generating response message.
645 * @param[in] ledState LED state passed from request
646 *
647 * @return None.
648 */
649void setIndicatorLedState(std::shared_ptr<AsyncResp> aResp,
650 const std::string &ledState)
651{
652 BMCWEB_LOG_DEBUG << "Set led groups";
653 bool ledOn = false;
654 bool ledBlinkng = false;
655
656 if (ledState == "Lit")
657 {
658 ledOn = true;
659 }
660 else if (ledState == "Blinking")
661 {
662 ledBlinkng = true;
663 }
664 else if (ledState != "Off")
665 {
666 messages::propertyValueNotInList(aResp->res, ledState, "IndicatorLED");
667 return;
668 }
669
670 crow::connections::systemBus->async_method_call(
AppaRao Pulif847a192019-11-15 14:57:44 +0530671 [aResp, ledOn, ledBlinkng](const boost::system::error_code ec,
672 const std::variant<bool> asserted) mutable {
AppaRao Pulia3002222019-11-12 21:32:59 +0530673 if (ec)
674 {
AppaRao Pulif847a192019-11-15 14:57:44 +0530675 // Some systems may not have enclosure_identify_blink object so
676 // Lets set enclosure_identify state to true if Blinking is
677 // true.
678 if (ledBlinkng)
679 {
680 ledOn = true;
681 }
Ed Tanous6c34de42018-08-29 13:37:36 -0700682 }
AppaRao Pulif847a192019-11-15 14:57:44 +0530683 crow::connections::systemBus->async_method_call(
684 [aResp](const boost::system::error_code ec,
685 const std::variant<bool> asserted) {
686 if (ec)
687 {
688 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
689 messages::internalError(aResp->res);
690 return;
691 }
692 },
693 "xyz.openbmc_project.LED.GroupManager",
694 "/xyz/openbmc_project/led/groups/enclosure_identify",
695 "org.freedesktop.DBus.Properties", "Set",
696 "xyz.openbmc_project.Led.Group", "Asserted",
697 std::variant<bool>(ledOn));
AppaRao Pulia3002222019-11-12 21:32:59 +0530698 },
699 "xyz.openbmc_project.LED.GroupManager",
700 "/xyz/openbmc_project/led/groups/enclosure_identify_blink",
701 "org.freedesktop.DBus.Properties", "Set",
702 "xyz.openbmc_project.Led.Group", "Asserted",
703 std::variant<bool>(ledBlinkng));
Ed Tanous6c34de42018-08-29 13:37:36 -0700704}
705
Ed Tanous6c34de42018-08-29 13:37:36 -0700706/**
707 * @brief Retrieves host state properties over dbus
708 *
709 * @param[in] aResp Shared pointer for completing asynchronous calls.
710 *
711 * @return None.
712 */
713void getHostState(std::shared_ptr<AsyncResp> aResp)
714{
715 BMCWEB_LOG_DEBUG << "Get host information.";
716 crow::connections::systemBus->async_method_call(
Jennifer Leec5d03ff2019-03-08 15:42:58 -0800717 [aResp](const boost::system::error_code ec,
718 const std::variant<std::string> &hostState) {
Ed Tanous6c34de42018-08-29 13:37:36 -0700719 if (ec)
720 {
721 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700722 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700723 return;
724 }
Ed Tanous66173382018-08-15 18:20:59 -0700725
Ed Tanousabf2add2019-01-22 16:40:12 -0800726 const std::string *s = std::get_if<std::string>(&hostState);
Ed Tanous66173382018-08-15 18:20:59 -0700727 BMCWEB_LOG_DEBUG << "Host state: " << *s;
728 if (s != nullptr)
Ed Tanous6c34de42018-08-29 13:37:36 -0700729 {
Ed Tanous66173382018-08-15 18:20:59 -0700730 // Verify Host State
Andrew Geissler94732662019-01-08 19:32:16 -0800731 if (*s == "xyz.openbmc_project.State.Host.HostState.Running")
Ed Tanous6c34de42018-08-29 13:37:36 -0700732 {
Ed Tanous66173382018-08-15 18:20:59 -0700733 aResp->res.jsonValue["PowerState"] = "On";
734 aResp->res.jsonValue["Status"]["State"] = "Enabled";
735 }
736 else
737 {
738 aResp->res.jsonValue["PowerState"] = "Off";
739 aResp->res.jsonValue["Status"]["State"] = "Disabled";
Ed Tanous6c34de42018-08-29 13:37:36 -0700740 }
741 }
742 },
743 "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
Ed Tanous66173382018-08-15 18:20:59 -0700744 "org.freedesktop.DBus.Properties", "Get",
745 "xyz.openbmc_project.State.Host", "CurrentHostState");
Ed Tanous6c34de42018-08-29 13:37:36 -0700746}
747
748/**
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530749 * @brief Traslates boot source DBUS property value to redfish.
750 *
751 * @param[in] dbusSource The boot source in DBUS speak.
752 *
753 * @return Returns as a string, the boot source in Redfish terms. If translation
754 * cannot be done, returns an empty string.
755 */
756static std::string dbusToRfBootSource(const std::string &dbusSource)
757{
758 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
759 {
760 return "None";
761 }
762 else if (dbusSource ==
763 "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
764 {
765 return "Hdd";
766 }
767 else if (dbusSource ==
Santosh Puranika71dc0b2019-05-23 20:10:49 +0530768 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530769 {
770 return "Cd";
771 }
772 else if (dbusSource ==
773 "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
774 {
775 return "Pxe";
776 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700777 else if (dbusSource ==
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700778 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700779 {
780 return "Usb";
781 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530782 else
783 {
784 return "";
785 }
786}
787
788/**
789 * @brief Traslates boot mode DBUS property value to redfish.
790 *
791 * @param[in] dbusMode The boot mode in DBUS speak.
792 *
793 * @return Returns as a string, the boot mode in Redfish terms. If translation
794 * cannot be done, returns an empty string.
795 */
796static std::string dbusToRfBootMode(const std::string &dbusMode)
797{
798 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
799 {
800 return "None";
801 }
802 else if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
803 {
804 return "Diags";
805 }
806 else if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
807 {
808 return "BiosSetup";
809 }
810 else
811 {
812 return "";
813 }
814}
815
816/**
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700817 * @brief Traslates boot source from Redfish to the DBus boot paths.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530818 *
819 * @param[in] rfSource The boot source in Redfish.
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700820 * @param[out] bootSource The DBus source
821 * @param[out] bootMode the DBus boot mode
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530822 *
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700823 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530824 */
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700825static int assignBootParameters(std::shared_ptr<AsyncResp> aResp,
826 const std::string &rfSource,
827 std::string &bootSource, std::string &bootMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530828{
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700829 // The caller has initialized the bootSource and bootMode to:
830 // bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
831 // bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
832 // Only modify the bootSource/bootMode variable needed to achieve the
833 // desired boot action.
834
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530835 if (rfSource == "None")
836 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700837 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530838 }
839 else if (rfSource == "Pxe")
840 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700841 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
842 }
843 else if (rfSource == "Hdd")
844 {
845 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
846 }
847 else if (rfSource == "Diags")
848 {
849 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
850 }
851 else if (rfSource == "Cd")
852 {
853 bootSource =
854 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
855 }
856 else if (rfSource == "BiosSetup")
857 {
858 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530859 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700860 else if (rfSource == "Usb")
861 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700862 bootSource =
863 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700864 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530865 else
866 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700867 BMCWEB_LOG_DEBUG << "Invalid property value for "
868 "BootSourceOverrideTarget: "
869 << bootSource;
870 messages::propertyValueNotInList(aResp->res, rfSource,
871 "BootSourceTargetOverride");
872 return -1;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530873 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700874 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530875}
876
877/**
878 * @brief Retrieves boot mode over DBUS and fills out the response
879 *
880 * @param[in] aResp Shared pointer for generating response message.
881 * @param[in] bootDbusObj The dbus object to query for boot properties.
882 *
883 * @return None.
884 */
885static void getBootMode(std::shared_ptr<AsyncResp> aResp,
886 std::string bootDbusObj)
887{
888 crow::connections::systemBus->async_method_call(
889 [aResp](const boost::system::error_code ec,
890 const std::variant<std::string> &bootMode) {
891 if (ec)
892 {
893 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
894 messages::internalError(aResp->res);
895 return;
896 }
897
898 const std::string *bootModeStr =
899 std::get_if<std::string>(&bootMode);
900
901 if (!bootModeStr)
902 {
903 messages::internalError(aResp->res);
904 return;
905 }
906
907 BMCWEB_LOG_DEBUG << "Boot mode: " << *bootModeStr;
908
909 // TODO (Santosh): Do we need to support override mode?
910 aResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = "Legacy";
911 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget@Redfish."
912 "AllowableValues"] = {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700913 "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530914
915 if (*bootModeStr !=
916 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
917 {
918 auto rfMode = dbusToRfBootMode(*bootModeStr);
919 if (!rfMode.empty())
920 {
921 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
922 rfMode;
923 }
924 }
925
926 // If the BootSourceOverrideTarget is still "None" at the end,
927 // reset the BootSourceOverrideEnabled to indicate that
928 // overrides are disabled
929 if (aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] ==
930 "None")
931 {
932 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
933 "Disabled";
934 }
935 },
936 "xyz.openbmc_project.Settings", bootDbusObj,
937 "org.freedesktop.DBus.Properties", "Get",
938 "xyz.openbmc_project.Control.Boot.Mode", "BootMode");
939}
940
941/**
942 * @brief Retrieves boot source over DBUS
943 *
944 * @param[in] aResp Shared pointer for generating response message.
945 * @param[in] oneTimeEnable Boolean to indicate boot properties are one-time.
946 *
947 * @return None.
948 */
949static void getBootSource(std::shared_ptr<AsyncResp> aResp, bool oneTimeEnabled)
950{
951 std::string bootDbusObj =
952 oneTimeEnabled ? "/xyz/openbmc_project/control/host0/boot/one_time"
953 : "/xyz/openbmc_project/control/host0/boot";
954
955 BMCWEB_LOG_DEBUG << "Is one time: " << oneTimeEnabled;
956 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
957 (oneTimeEnabled) ? "Once" : "Continuous";
958
959 crow::connections::systemBus->async_method_call(
960 [aResp, bootDbusObj](const boost::system::error_code ec,
961 const std::variant<std::string> &bootSource) {
962 if (ec)
963 {
964 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
965 messages::internalError(aResp->res);
966 return;
967 }
968
969 const std::string *bootSourceStr =
970 std::get_if<std::string>(&bootSource);
971
972 if (!bootSourceStr)
973 {
974 messages::internalError(aResp->res);
975 return;
976 }
977 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSourceStr;
978
979 auto rfSource = dbusToRfBootSource(*bootSourceStr);
980 if (!rfSource.empty())
981 {
982 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
983 rfSource;
984 }
985 },
986 "xyz.openbmc_project.Settings", bootDbusObj,
987 "org.freedesktop.DBus.Properties", "Get",
988 "xyz.openbmc_project.Control.Boot.Source", "BootSource");
989 getBootMode(std::move(aResp), std::move(bootDbusObj));
990}
991
992/**
993 * @brief Retrieves "One time" enabled setting over DBUS and calls function to
994 * get boot source and boot mode.
995 *
996 * @param[in] aResp Shared pointer for generating response message.
997 *
998 * @return None.
999 */
1000static void getBootProperties(std::shared_ptr<AsyncResp> aResp)
1001{
1002 BMCWEB_LOG_DEBUG << "Get boot information.";
1003
1004 crow::connections::systemBus->async_method_call(
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001005 [aResp](const boost::system::error_code ec,
1006 const sdbusplus::message::variant<bool> &oneTime) {
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301007 if (ec)
1008 {
1009 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
James Feist2a833c72019-07-19 10:17:13 -07001010 // not an error, don't have to have the interface
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301011 return;
1012 }
1013
1014 const bool *oneTimePtr = std::get_if<bool>(&oneTime);
1015
1016 if (!oneTimePtr)
1017 {
1018 messages::internalError(aResp->res);
1019 return;
1020 }
1021 getBootSource(aResp, *oneTimePtr);
1022 },
1023 "xyz.openbmc_project.Settings",
1024 "/xyz/openbmc_project/control/host0/boot/one_time",
1025 "org.freedesktop.DBus.Properties", "Get",
1026 "xyz.openbmc_project.Object.Enable", "Enabled");
1027}
1028
1029/**
1030 * @brief Sets boot properties into DBUS object(s).
1031 *
1032 * @param[in] aResp Shared pointer for generating response message.
1033 * @param[in] oneTimeEnabled Is "one-time" setting already enabled.
1034 * @param[in] bootSource The boot source to set.
1035 * @param[in] bootEnable The source override "enable" to set.
1036 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001037 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301038 */
1039static void setBootModeOrSource(std::shared_ptr<AsyncResp> aResp,
1040 bool oneTimeEnabled,
1041 std::optional<std::string> bootSource,
1042 std::optional<std::string> bootEnable)
1043{
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001044 std::string bootSourceStr =
1045 "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
1046 std::string bootModeStr =
1047 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301048 bool oneTimeSetting = oneTimeEnabled;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001049 bool useBootSource = true;
1050
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301051 // Validate incoming parameters
1052 if (bootEnable)
1053 {
1054 if (*bootEnable == "Once")
1055 {
1056 oneTimeSetting = true;
1057 }
1058 else if (*bootEnable == "Continuous")
1059 {
1060 oneTimeSetting = false;
1061 }
1062 else if (*bootEnable == "Disabled")
1063 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001064 BMCWEB_LOG_DEBUG << "Boot source override will be disabled";
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301065 oneTimeSetting = false;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001066 useBootSource = false;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301067 }
1068 else
1069 {
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301070 BMCWEB_LOG_DEBUG << "Unsupported value for "
1071 "BootSourceOverrideEnabled: "
1072 << *bootEnable;
1073 messages::propertyValueNotInList(aResp->res, *bootEnable,
1074 "BootSourceOverrideEnabled");
1075 return;
1076 }
1077 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301078
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001079 if (bootSource && useBootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301080 {
1081 // Source target specified
1082 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource;
1083 // Figure out which DBUS interface and property to use
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001084 if (assignBootParameters(aResp, *bootSource, bootSourceStr,
1085 bootModeStr))
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301086 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001087 BMCWEB_LOG_DEBUG
1088 << "Invalid property value for BootSourceOverrideTarget: "
1089 << *bootSource;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301090 messages::propertyValueNotInList(aResp->res, *bootSource,
1091 "BootSourceTargetOverride");
1092 return;
1093 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001094 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301095
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001096 // Act on validated parameters
1097 BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
1098 BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;
1099 const char *bootObj =
1100 oneTimeSetting ? "/xyz/openbmc_project/control/host0/boot/one_time"
1101 : "/xyz/openbmc_project/control/host0/boot";
1102
1103 crow::connections::systemBus->async_method_call(
1104 [aResp](const boost::system::error_code ec) {
1105 if (ec)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301106 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001107 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1108 messages::internalError(aResp->res);
1109 return;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301110 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001111 BMCWEB_LOG_DEBUG << "Boot source update done.";
1112 },
1113 "xyz.openbmc_project.Settings", bootObj,
1114 "org.freedesktop.DBus.Properties", "Set",
1115 "xyz.openbmc_project.Control.Boot.Source", "BootSource",
1116 std::variant<std::string>(bootSourceStr));
1117
1118 crow::connections::systemBus->async_method_call(
1119 [aResp](const boost::system::error_code ec) {
1120 if (ec)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301121 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001122 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1123 messages::internalError(aResp->res);
1124 return;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301125 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001126 BMCWEB_LOG_DEBUG << "Boot mode update done.";
1127 },
1128 "xyz.openbmc_project.Settings", bootObj,
1129 "org.freedesktop.DBus.Properties", "Set",
1130 "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
1131 std::variant<std::string>(bootModeStr));
1132
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301133 crow::connections::systemBus->async_method_call(
1134 [aResp{std::move(aResp)}](const boost::system::error_code ec) {
1135 if (ec)
1136 {
1137 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1138 messages::internalError(aResp->res);
1139 return;
1140 }
1141 BMCWEB_LOG_DEBUG << "Boot enable update done.";
1142 },
1143 "xyz.openbmc_project.Settings",
1144 "/xyz/openbmc_project/control/host0/boot/one_time",
1145 "org.freedesktop.DBus.Properties", "Set",
1146 "xyz.openbmc_project.Object.Enable", "Enabled",
1147 std::variant<bool>(oneTimeSetting));
1148}
1149
1150/**
1151 * @brief Retrieves "One time" enabled setting over DBUS and calls function to
1152 * set boot source/boot mode properties.
1153 *
1154 * @param[in] aResp Shared pointer for generating response message.
1155 * @param[in] bootSource The boot source from incoming RF request.
1156 * @param[in] bootEnable The boot override enable from incoming RF request.
1157 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001158 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301159 */
1160static void setBootProperties(std::shared_ptr<AsyncResp> aResp,
1161 std::optional<std::string> bootSource,
1162 std::optional<std::string> bootEnable)
1163{
1164 BMCWEB_LOG_DEBUG << "Set boot information.";
1165
1166 crow::connections::systemBus->async_method_call(
Johnathan Mantey265c1602019-08-08 11:02:51 -07001167 [aResp, bootSource{std::move(bootSource)},
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301168 bootEnable{std::move(bootEnable)}](
1169 const boost::system::error_code ec,
1170 const sdbusplus::message::variant<bool> &oneTime) {
1171 if (ec)
1172 {
1173 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1174 messages::internalError(aResp->res);
1175 return;
1176 }
1177
1178 const bool *oneTimePtr = std::get_if<bool>(&oneTime);
1179
1180 if (!oneTimePtr)
1181 {
1182 messages::internalError(aResp->res);
1183 return;
1184 }
1185
1186 BMCWEB_LOG_DEBUG << "Got one time: " << *oneTimePtr;
1187
1188 setBootModeOrSource(aResp, *oneTimePtr, std::move(bootSource),
1189 std::move(bootEnable));
1190 },
1191 "xyz.openbmc_project.Settings",
1192 "/xyz/openbmc_project/control/host0/boot/one_time",
1193 "org.freedesktop.DBus.Properties", "Get",
1194 "xyz.openbmc_project.Object.Enable", "Enabled");
1195}
1196
AppaRao Pulia6349912019-10-18 17:16:08 +05301197#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1198/**
1199 * @brief Retrieves provisioning status
1200 *
1201 * @param[in] aResp Shared pointer for completing asynchronous calls.
1202 *
1203 * @return None.
1204 */
1205void getProvisioningStatus(std::shared_ptr<AsyncResp> aResp)
1206{
1207 BMCWEB_LOG_DEBUG << "Get OEM information.";
1208 crow::connections::systemBus->async_method_call(
1209 [aResp](const boost::system::error_code ec,
1210 const std::vector<std::pair<std::string, VariantType>>
1211 &propertiesList) {
1212 if (ec)
1213 {
1214 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1215 messages::internalError(aResp->res);
1216 return;
1217 }
1218
1219 const bool *provState = nullptr;
1220 const bool *lockState = nullptr;
1221 for (const std::pair<std::string, VariantType> &property :
1222 propertiesList)
1223 {
1224 if (property.first == "UfmProvisioned")
1225 {
1226 provState = std::get_if<bool>(&property.second);
1227 }
1228 else if (property.first == "UfmLocked")
1229 {
1230 lockState = std::get_if<bool>(&property.second);
1231 }
1232 }
1233
1234 if ((provState == nullptr) || (lockState == nullptr))
1235 {
1236 BMCWEB_LOG_DEBUG << "Unable to get PFR attributes.";
1237 messages::internalError(aResp->res);
1238 return;
1239 }
1240
1241 nlohmann::json &oemPFR =
1242 aResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
1243 if (*provState == true)
1244 {
1245 if (*lockState == true)
1246 {
1247 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
1248 }
1249 else
1250 {
1251 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
1252 }
1253 }
1254 else
1255 {
1256 oemPFR["ProvisioningStatus"] = "NotProvisioned";
1257 }
1258 },
1259 "xyz.openbmc_project.PFR.Manager", "/xyz/openbmc_project/pfr",
1260 "org.freedesktop.DBus.Properties", "GetAll",
1261 "xyz.openbmc_project.PFR.Attributes");
1262}
1263#endif
1264
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301265/**
Yong Li51709ff2019-09-30 14:13:04 +08001266 * @brief Translates watchdog timeout action DBUS property value to redfish.
1267 *
1268 * @param[in] dbusAction The watchdog timeout action in D-BUS.
1269 *
1270 * @return Returns as a string, the timeout action in Redfish terms. If
1271 * translation cannot be done, returns an empty string.
1272 */
1273static std::string dbusToRfWatchdogAction(const std::string &dbusAction)
1274{
1275 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
1276 {
1277 return "None";
1278 }
1279 else if (dbusAction ==
1280 "xyz.openbmc_project.State.Watchdog.Action.HardReset")
1281 {
1282 return "ResetSystem";
1283 }
1284 else if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
1285 {
1286 return "PowerDown";
1287 }
1288 else if (dbusAction ==
1289 "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
1290 {
1291 return "PowerCycle";
1292 }
1293
1294 return "";
1295}
1296
1297/**
Yong Lic45f0082019-10-10 14:19:01 +08001298 *@brief Translates timeout action from Redfish to DBUS property value.
1299 *
1300 *@param[in] rfAction The timeout action in Redfish.
1301 *
1302 *@return Returns as a string, the time_out action as expected by DBUS.
1303 *If translation cannot be done, returns an empty string.
1304 */
1305
1306static std::string rfToDbusWDTTimeOutAct(const std::string &rfAction)
1307{
1308 if (rfAction == "None")
1309 {
1310 return "xyz.openbmc_project.State.Watchdog.Action.None";
1311 }
1312 else if (rfAction == "PowerCycle")
1313 {
1314 return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
1315 }
1316 else if (rfAction == "PowerDown")
1317 {
1318 return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
1319 }
1320 else if (rfAction == "ResetSystem")
1321 {
1322 return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
1323 }
1324
1325 return "";
1326}
1327
1328/**
Yong Li51709ff2019-09-30 14:13:04 +08001329 * @brief Retrieves host watchdog timer properties over DBUS
1330 *
1331 * @param[in] aResp Shared pointer for completing asynchronous calls.
1332 *
1333 * @return None.
1334 */
1335void getHostWatchdogTimer(std::shared_ptr<AsyncResp> aResp)
1336{
1337 BMCWEB_LOG_DEBUG << "Get host watchodg";
1338 crow::connections::systemBus->async_method_call(
1339 [aResp](const boost::system::error_code ec,
1340 PropertiesType &properties) {
1341 if (ec)
1342 {
1343 // watchdog service is stopped
1344 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1345 return;
1346 }
1347
1348 BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop.";
1349
1350 nlohmann::json &hostWatchdogTimer =
1351 aResp->res.jsonValue["HostWatchdogTimer"];
1352
1353 // watchdog service is running/enabled
1354 hostWatchdogTimer["Status"]["State"] = "Enabled";
1355
1356 for (const auto &property : properties)
1357 {
1358 BMCWEB_LOG_DEBUG << "prop=" << property.first;
1359 if (property.first == "Enabled")
1360 {
1361 const bool *state = std::get_if<bool>(&property.second);
1362
1363 if (!state)
1364 {
1365 messages::internalError(aResp->res);
1366 continue;
1367 }
1368
1369 hostWatchdogTimer["FunctionEnabled"] = *state;
1370 }
1371 else if (property.first == "ExpireAction")
1372 {
1373 const std::string *s =
1374 std::get_if<std::string>(&property.second);
1375 if (!s)
1376 {
1377 messages::internalError(aResp->res);
1378 continue;
1379 }
1380
1381 std::string action = dbusToRfWatchdogAction(*s);
1382 if (action.empty())
1383 {
1384 messages::internalError(aResp->res);
1385 continue;
1386 }
1387 hostWatchdogTimer["TimeoutAction"] = action;
1388 }
1389 }
1390 },
1391 "xyz.openbmc_project.Watchdog", "/xyz/openbmc_project/watchdog/host0",
1392 "org.freedesktop.DBus.Properties", "GetAll",
1393 "xyz.openbmc_project.State.Watchdog");
1394}
1395
1396/**
Yong Lic45f0082019-10-10 14:19:01 +08001397 * @brief Sets Host WatchDog Timer properties.
1398 *
1399 * @param[in] aResp Shared pointer for generating response message.
1400 * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming
1401 * RF request.
1402 * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
1403 *
1404 * @return None.
1405 */
1406static void setWDTProperties(std::shared_ptr<AsyncResp> aResp,
1407 const std::optional<bool> wdtEnable,
1408 const std::optional<std::string> &wdtTimeOutAction)
1409{
1410 BMCWEB_LOG_DEBUG << "Set host watchdog";
1411
1412 if (wdtTimeOutAction)
1413 {
1414 std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
1415 // check if TimeOut Action is Valid
1416 if (wdtTimeOutActStr.empty())
1417 {
1418 BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: "
1419 << *wdtTimeOutAction;
1420 messages::propertyValueNotInList(aResp->res, *wdtTimeOutAction,
1421 "TimeoutAction");
1422 return;
1423 }
1424
1425 crow::connections::systemBus->async_method_call(
1426 [aResp](const boost::system::error_code ec) {
1427 if (ec)
1428 {
1429 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1430 messages::internalError(aResp->res);
1431 return;
1432 }
1433 },
1434 "xyz.openbmc_project.Watchdog",
1435 "/xyz/openbmc_project/watchdog/host0",
1436 "org.freedesktop.DBus.Properties", "Set",
1437 "xyz.openbmc_project.State.Watchdog", "ExpireAction",
1438 std::variant<std::string>(wdtTimeOutActStr));
1439 }
1440
1441 if (wdtEnable)
1442 {
1443 crow::connections::systemBus->async_method_call(
1444 [aResp](const boost::system::error_code ec) {
1445 if (ec)
1446 {
1447 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1448 messages::internalError(aResp->res);
1449 return;
1450 }
1451 },
1452 "xyz.openbmc_project.Watchdog",
1453 "/xyz/openbmc_project/watchdog/host0",
1454 "org.freedesktop.DBus.Properties", "Set",
1455 "xyz.openbmc_project.State.Watchdog", "Enabled",
1456 std::variant<bool>(*wdtEnable));
1457 }
1458}
1459
1460/**
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001461 * SystemsCollection derived class for delivering ComputerSystems Collection
1462 * Schema
1463 */
Ed Tanous1abe55e2018-09-05 08:30:59 -07001464class SystemsCollection : public Node
1465{
1466 public:
1467 SystemsCollection(CrowApp &app) : Node(app, "/redfish/v1/Systems/")
1468 {
Ed Tanous1abe55e2018-09-05 08:30:59 -07001469 entityPrivileges = {
1470 {boost::beast::http::verb::get, {{"Login"}}},
1471 {boost::beast::http::verb::head, {{"Login"}}},
1472 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1473 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1474 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1475 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1476 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001477
Ed Tanous1abe55e2018-09-05 08:30:59 -07001478 private:
Ed Tanous1abe55e2018-09-05 08:30:59 -07001479 void doGet(crow::Response &res, const crow::Request &req,
1480 const std::vector<std::string> &params) override
1481 {
Ed Tanous0f74e642018-11-12 15:17:05 -08001482 res.jsonValue["@odata.type"] =
1483 "#ComputerSystemCollection.ComputerSystemCollection";
1484 res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
1485 res.jsonValue["@odata.context"] =
1486 "/redfish/v1/"
1487 "$metadata#ComputerSystemCollection.ComputerSystemCollection";
1488 res.jsonValue["Name"] = "Computer System Collection";
Ed Tanous029573d2019-02-01 10:57:49 -08001489 res.jsonValue["Members"] = {
1490 {{"@odata.id", "/redfish/v1/Systems/system"}}};
1491 res.jsonValue["Members@odata.count"] = 1;
1492 res.end();
Ed Tanous1abe55e2018-09-05 08:30:59 -07001493 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001494};
1495
1496/**
Ed Tanouscc340dd2018-08-29 13:43:38 -07001497 * SystemActionsReset class supports handle POST method for Reset action.
1498 * The class retrieves and sends data directly to D-Bus.
1499 */
1500class SystemActionsReset : public Node
1501{
1502 public:
1503 SystemActionsReset(CrowApp &app) :
Ed Tanous029573d2019-02-01 10:57:49 -08001504 Node(app, "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/")
Ed Tanouscc340dd2018-08-29 13:43:38 -07001505 {
1506 entityPrivileges = {
1507 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1508 }
1509
1510 private:
1511 /**
1512 * Function handles POST method request.
1513 * Analyzes POST body message before sends Reset request data to D-Bus.
1514 */
1515 void doPost(crow::Response &res, const crow::Request &req,
1516 const std::vector<std::string> &params) override
1517 {
Ed Tanous9712f8a2018-09-21 13:38:49 -07001518 auto asyncResp = std::make_shared<AsyncResp>(res);
1519
1520 std::string resetType;
1521 if (!json_util::readJson(req, res, "ResetType", resetType))
Ed Tanouscc340dd2018-08-29 13:43:38 -07001522 {
1523 return;
1524 }
1525
Jason M. Billsd22c8392019-06-03 13:59:03 -07001526 // Get the command and host vs. chassis
Ed Tanous9712f8a2018-09-21 13:38:49 -07001527 std::string command;
Jason M. Billsd22c8392019-06-03 13:59:03 -07001528 bool hostCommand;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001529 if (resetType == "On")
1530 {
1531 command = "xyz.openbmc_project.State.Host.Transition.On";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001532 hostCommand = true;
1533 }
1534 else if (resetType == "ForceOff")
1535 {
1536 command = "xyz.openbmc_project.State.Chassis.Transition.Off";
1537 hostCommand = false;
1538 }
1539 else if (resetType == "ForceOn")
1540 {
1541 command = "xyz.openbmc_project.State.Host.Transition.On";
1542 hostCommand = true;
1543 }
1544 else if (resetType == "ForceRestart")
1545 {
1546 command = "xyz.openbmc_project.State.Chassis.Transition.Reset";
1547 hostCommand = false;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001548 }
1549 else if (resetType == "GracefulShutdown")
1550 {
1551 command = "xyz.openbmc_project.State.Host.Transition.Off";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001552 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001553 }
1554 else if (resetType == "GracefulRestart")
1555 {
1556 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001557 hostCommand = true;
1558 }
1559 else if (resetType == "PowerCycle")
1560 {
1561 command = "xyz.openbmc_project.State.Chassis.Transition.PowerCycle";
1562 hostCommand = false;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001563 }
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001564 else if (resetType == "Nmi")
1565 {
1566 doNMI(asyncResp);
1567 return;
1568 }
Ed Tanous9712f8a2018-09-21 13:38:49 -07001569 else
1570 {
Jason M. Billsf12894f2018-10-09 12:45:45 -07001571 messages::actionParameterUnknown(res, "Reset", resetType);
Ed Tanous9712f8a2018-09-21 13:38:49 -07001572 return;
1573 }
1574
Jason M. Billsd22c8392019-06-03 13:59:03 -07001575 if (hostCommand)
1576 {
1577 crow::connections::systemBus->async_method_call(
1578 [asyncResp, resetType](const boost::system::error_code ec) {
1579 if (ec)
1580 {
1581 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1582 if (ec.value() == boost::asio::error::invalid_argument)
1583 {
1584 messages::actionParameterNotSupported(
1585 asyncResp->res, resetType, "Reset");
1586 }
1587 else
1588 {
1589 messages::internalError(asyncResp->res);
1590 }
1591 return;
1592 }
1593 messages::success(asyncResp->res);
1594 },
1595 "xyz.openbmc_project.State.Host",
1596 "/xyz/openbmc_project/state/host0",
1597 "org.freedesktop.DBus.Properties", "Set",
1598 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
1599 std::variant<std::string>{command});
1600 }
1601 else
1602 {
1603 crow::connections::systemBus->async_method_call(
1604 [asyncResp, resetType](const boost::system::error_code ec) {
1605 if (ec)
1606 {
1607 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1608 if (ec.value() == boost::asio::error::invalid_argument)
1609 {
1610 messages::actionParameterNotSupported(
1611 asyncResp->res, resetType, "Reset");
1612 }
1613 else
1614 {
1615 messages::internalError(asyncResp->res);
1616 }
1617 return;
1618 }
1619 messages::success(asyncResp->res);
1620 },
1621 "xyz.openbmc_project.State.Chassis",
1622 "/xyz/openbmc_project/state/chassis0",
1623 "org.freedesktop.DBus.Properties", "Set",
1624 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
1625 std::variant<std::string>{command});
1626 }
Ed Tanouscc340dd2018-08-29 13:43:38 -07001627 }
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001628 /**
1629 * Function transceives data with dbus directly.
1630 */
1631 void doNMI(const std::shared_ptr<AsyncResp> &asyncResp)
1632 {
1633 constexpr char const *serviceName =
1634 "xyz.openbmc_project.Control.Host.NMI";
1635 constexpr char const *objectPath =
1636 "/xyz/openbmc_project/control/host0/nmi";
1637 constexpr char const *interfaceName =
1638 "xyz.openbmc_project.Control.Host.NMI";
1639 constexpr char const *method = "NMI";
1640
1641 crow::connections::systemBus->async_method_call(
1642 [asyncResp](const boost::system::error_code ec) {
1643 if (ec)
1644 {
1645 BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
1646 messages::internalError(asyncResp->res);
1647 return;
1648 }
1649 messages::success(asyncResp->res);
1650 },
1651 serviceName, objectPath, interfaceName, method);
1652 }
Ed Tanouscc340dd2018-08-29 13:43:38 -07001653};
1654
1655/**
Ed Tanous66173382018-08-15 18:20:59 -07001656 * Systems derived class for delivering Computer Systems Schema.
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001657 */
Ed Tanous1abe55e2018-09-05 08:30:59 -07001658class Systems : public Node
1659{
1660 public:
1661 /*
1662 * Default Constructor
1663 */
Ed Tanous029573d2019-02-01 10:57:49 -08001664 Systems(CrowApp &app) : Node(app, "/redfish/v1/Systems/system/")
Ed Tanous1abe55e2018-09-05 08:30:59 -07001665 {
Ed Tanous1abe55e2018-09-05 08:30:59 -07001666 entityPrivileges = {
1667 {boost::beast::http::verb::get, {{"Login"}}},
1668 {boost::beast::http::verb::head, {{"Login"}}},
1669 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1670 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1671 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1672 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001673 }
1674
Ed Tanous1abe55e2018-09-05 08:30:59 -07001675 private:
Ed Tanous1abe55e2018-09-05 08:30:59 -07001676 /**
1677 * Functions triggers appropriate requests on DBus
1678 */
1679 void doGet(crow::Response &res, const crow::Request &req,
1680 const std::vector<std::string> &params) override
1681 {
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301682 res.jsonValue["@odata.type"] = "#ComputerSystem.v1_6_0.ComputerSystem";
Ed Tanous0f74e642018-11-12 15:17:05 -08001683 res.jsonValue["@odata.context"] =
1684 "/redfish/v1/$metadata#ComputerSystem.ComputerSystem";
Ed Tanous029573d2019-02-01 10:57:49 -08001685 res.jsonValue["Name"] = "Computer System";
1686 res.jsonValue["Id"] = "system";
Ed Tanous0f74e642018-11-12 15:17:05 -08001687 res.jsonValue["SystemType"] = "Physical";
1688 res.jsonValue["Description"] = "Computer System";
Ed Tanous0f74e642018-11-12 15:17:05 -08001689 res.jsonValue["ProcessorSummary"]["Count"] = 0;
1690 res.jsonValue["ProcessorSummary"]["Status"]["State"] = "Disabled";
Cheng C Yang5fd7ba62019-11-28 15:58:08 +08001691 res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = uint64_t(0);
Ed Tanous0f74e642018-11-12 15:17:05 -08001692 res.jsonValue["MemorySummary"]["Status"]["State"] = "Disabled";
Ed Tanous029573d2019-02-01 10:57:49 -08001693 res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
Ed Tanous04a258f2018-10-15 08:00:41 -07001694
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001695 res.jsonValue["Processors"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001696 {"@odata.id", "/redfish/v1/Systems/system/Processors"}};
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001697 res.jsonValue["Memory"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001698 {"@odata.id", "/redfish/v1/Systems/system/Memory"}};
Nikhil Potadea25aecc2019-08-23 16:35:26 -07001699 res.jsonValue["Storage"] = {
1700 {"@odata.id", "/redfish/v1/Systems/system/Storage"}};
Ed Tanous029573d2019-02-01 10:57:49 -08001701
Ed Tanouscc340dd2018-08-29 13:43:38 -07001702 // TODO Need to support ForceRestart.
1703 res.jsonValue["Actions"]["#ComputerSystem.Reset"] = {
1704 {"target",
Ed Tanous029573d2019-02-01 10:57:49 -08001705 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"},
Ed Tanouscc340dd2018-08-29 13:43:38 -07001706 {"ResetType@Redfish.AllowableValues",
Jason M. Billsd22c8392019-06-03 13:59:03 -07001707 {"On", "ForceOff", "ForceOn", "ForceRestart", "GracefulRestart",
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001708 "GracefulShutdown", "PowerCycle", "Nmi"}}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001709
Jason M. Billsc4bf6372018-11-05 13:48:27 -08001710 res.jsonValue["LogServices"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001711 {"@odata.id", "/redfish/v1/Systems/system/LogServices"}};
Jason M. Billsc4bf6372018-11-05 13:48:27 -08001712
Carol Wangd82a3ac2019-11-21 13:56:38 +08001713 res.jsonValue["Bios"] = {
1714 {"@odata.id", "/redfish/v1/Systems/system/Bios"}};
1715
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001716 res.jsonValue["Links"]["ManagedBy"] = {
1717 {{"@odata.id", "/redfish/v1/Managers/bmc"}}};
1718
1719 res.jsonValue["Status"] = {
1720 {"Health", "OK"},
1721 {"State", "Enabled"},
1722 };
Ed Tanousa0803ef2018-08-29 13:29:23 -07001723 auto asyncResp = std::make_shared<AsyncResp>(res);
Ed Tanous1abe55e2018-09-05 08:30:59 -07001724
James Feiste284a7c2019-11-20 16:20:23 -08001725 constexpr const std::array<const char *, 4> inventoryForSystems = {
James Feistb49ac872019-05-21 15:12:01 -07001726 "xyz.openbmc_project.Inventory.Item.Dimm",
James Feist2ad9c2f2019-10-29 16:26:48 -07001727 "xyz.openbmc_project.Inventory.Item.Cpu",
James Feiste284a7c2019-11-20 16:20:23 -08001728 "xyz.openbmc_project.Inventory.Item.Drive",
1729 "xyz.openbmc_project.Inventory.Item.StorageController"};
James Feistb49ac872019-05-21 15:12:01 -07001730
1731 auto health = std::make_shared<HealthPopulate>(asyncResp);
1732 crow::connections::systemBus->async_method_call(
1733 [health](const boost::system::error_code ec,
1734 std::vector<std::string> &resp) {
1735 if (ec)
1736 {
1737 // no inventory
1738 return;
1739 }
1740
1741 health->inventory = std::move(resp);
1742 },
1743 "xyz.openbmc_project.ObjectMapper",
1744 "/xyz/openbmc_project/object_mapper",
1745 "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", "/",
1746 int32_t(0), inventoryForSystems);
1747
1748 health->populate();
1749
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001750 getMainChassisId(asyncResp, [](const std::string &chassisId,
1751 std::shared_ptr<AsyncResp> aRsp) {
1752 aRsp->res.jsonValue["Links"]["Chassis"] = {
1753 {{"@odata.id", "/redfish/v1/Chassis/" + chassisId}}};
1754 });
AppaRao Pulia3002222019-11-12 21:32:59 +05301755
1756 getIndicatorLedState(asyncResp);
James Feist5bc2dc82019-10-22 14:33:16 -07001757 getComputerSystem(asyncResp, health);
Ed Tanous6c34de42018-08-29 13:37:36 -07001758 getHostState(asyncResp);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301759 getBootProperties(asyncResp);
Jason M. Billsadbe1922019-10-14 15:44:35 -07001760 getPCIeDeviceList(asyncResp, "PCIeDevices");
Yong Li51709ff2019-09-30 14:13:04 +08001761 getHostWatchdogTimer(asyncResp);
AppaRao Pulia6349912019-10-18 17:16:08 +05301762#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1763 getProvisioningStatus(asyncResp);
1764#endif
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001765 }
1766
Ed Tanous1abe55e2018-09-05 08:30:59 -07001767 void doPatch(crow::Response &res, const crow::Request &req,
1768 const std::vector<std::string> &params) override
1769 {
Santosh Puranikcde19e52019-02-20 00:10:56 +05301770 std::optional<std::string> indicatorLed;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301771 std::optional<nlohmann::json> bootProps;
Yong Lic45f0082019-10-10 14:19:01 +08001772 std::optional<nlohmann::json> wdtTimerProps;
Santosh Puranik41352c22019-07-03 05:35:49 -05001773 auto asyncResp = std::make_shared<AsyncResp>(res);
1774
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001775 if (!json_util::readJson(req, res, "IndicatorLED", indicatorLed, "Boot",
Yong Lic45f0082019-10-10 14:19:01 +08001776 bootProps, "WatchdogTimer", wdtTimerProps))
Ed Tanous66173382018-08-15 18:20:59 -07001777 {
Ed Tanous9712f8a2018-09-21 13:38:49 -07001778 return;
1779 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301780
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001781 res.result(boost::beast::http::status::no_content);
Yong Lic45f0082019-10-10 14:19:01 +08001782
1783 if (wdtTimerProps)
1784 {
1785 std::optional<bool> wdtEnable;
1786 std::optional<std::string> wdtTimeOutAction;
1787
1788 if (!json_util::readJson(*wdtTimerProps, asyncResp->res,
1789 "FunctionEnabled", wdtEnable,
1790 "TimeoutAction", wdtTimeOutAction))
1791 {
1792 return;
1793 }
1794 setWDTProperties(asyncResp, std::move(wdtEnable),
1795 std::move(wdtTimeOutAction));
1796 }
1797
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301798 if (bootProps)
1799 {
1800 std::optional<std::string> bootSource;
1801 std::optional<std::string> bootEnable;
1802
1803 if (!json_util::readJson(*bootProps, asyncResp->res,
1804 "BootSourceOverrideTarget", bootSource,
1805 "BootSourceOverrideEnabled", bootEnable))
1806 {
1807 return;
1808 }
1809 setBootProperties(asyncResp, std::move(bootSource),
1810 std::move(bootEnable));
1811 }
Johnathan Mantey265c1602019-08-08 11:02:51 -07001812
Ed Tanous9712f8a2018-09-21 13:38:49 -07001813 if (indicatorLed)
1814 {
AppaRao Pulia3002222019-11-12 21:32:59 +05301815 setIndicatorLedState(asyncResp, std::move(*indicatorLed));
Ed Tanous1abe55e2018-09-05 08:30:59 -07001816 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001817 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001818};
Ed Tanous1abe55e2018-09-05 08:30:59 -07001819} // namespace redfish