xref: /openbmc/bmcweb/features/redfish/lib/log_services.hpp (revision 08fad5d9dc59323a8916ff97a035221621047d8c)
140e9b92eSEd Tanous // SPDX-License-Identifier: Apache-2.0
240e9b92eSEd Tanous // SPDX-FileCopyrightText: Copyright OpenBMC Authors
340e9b92eSEd Tanous // SPDX-FileCopyrightText: Copyright 2018 Intel Corporation
41da66f75SEd Tanous #pragma once
51da66f75SEd Tanous 
6d7857201SEd Tanous #include "bmcweb_config.h"
7d7857201SEd Tanous 
83ccb3adbSEd Tanous #include "app.hpp"
9d7857201SEd Tanous #include "async_resp.hpp"
10d7857201SEd Tanous #include "dbus_singleton.hpp"
117a1dbc48SGeorge Liu #include "dbus_utility.hpp"
123ccb3adbSEd Tanous #include "error_messages.hpp"
1368dd075aSAsmitha Karunanithi #include "generated/enums/log_entry.hpp"
14539d8c6bSEd Tanous #include "generated/enums/log_service.hpp"
15d7857201SEd Tanous #include "http_body.hpp"
16d7857201SEd Tanous #include "http_request.hpp"
17d7857201SEd Tanous #include "http_response.hpp"
18647b3cdcSGeorge Liu #include "http_utility.hpp"
19b7028ebfSSpencer Ku #include "human_sort.hpp"
20d7857201SEd Tanous #include "logging.hpp"
213ccb3adbSEd Tanous #include "query.hpp"
223ccb3adbSEd Tanous #include "registries/privilege_registry.hpp"
23d7857201SEd Tanous #include "str_utility.hpp"
2446229577SJames Feist #include "task.hpp"
255b90429aSEd Tanous #include "task_messages.hpp"
26262dcc1cSAlexander Hansen #include "utils/dbus_event_log_entry.hpp"
273ccb3adbSEd Tanous #include "utils/dbus_utils.hpp"
28*08fad5d9SCorey Ethington #include "utils/etag_utils.hpp"
295b90429aSEd Tanous #include "utils/json_utils.hpp"
30ff35df94SOliver Brewka #include "utils/log_services_utils.hpp"
313ccb3adbSEd Tanous #include "utils/time_utils.hpp"
321da66f75SEd Tanous 
33d7857201SEd Tanous #include <asm-generic/errno.h>
34d7857201SEd Tanous #include <systemd/sd-bus.h>
358e31778eSAsmitha Karunanithi #include <tinyxml2.h>
36400fd1fbSAdriana Kobylak #include <unistd.h>
37e1f26343SJason M. Bills 
38d7857201SEd Tanous #include <boost/beast/http/field.hpp>
39d7857201SEd Tanous #include <boost/beast/http/status.hpp>
4007c8c20dSEd Tanous #include <boost/beast/http/verb.hpp>
411ddcf01aSJason M. Bills #include <boost/system/linux_error.hpp>
42ef4c65b7SEd Tanous #include <boost/url/format.hpp>
43d7857201SEd Tanous #include <boost/url/url.hpp>
44d7857201SEd Tanous #include <sdbusplus/message.hpp>
45d7857201SEd Tanous #include <sdbusplus/message/native_types.hpp>
46d1bde9e5SKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp>
471214b7e7SGunnar Mills 
48d7857201SEd Tanous #include <algorithm>
497a1dbc48SGeorge Liu #include <array>
50d7857201SEd Tanous #include <chrono>
51d7857201SEd Tanous #include <cstdint>
524418c7f0SJames Feist #include <filesystem>
53d7857201SEd Tanous #include <format>
54d7857201SEd Tanous #include <functional>
5518f8f608SEd Tanous #include <iterator>
56d7857201SEd Tanous #include <memory>
5775710de2SXiaochao Ma #include <optional>
583544d2a7SEd Tanous #include <ranges>
5926702d01SEd Tanous #include <span>
6018f8f608SEd Tanous #include <string>
61cd225da8SJason M. Bills #include <string_view>
62d7857201SEd Tanous #include <utility>
63abf2add6SEd Tanous #include <variant>
64d7857201SEd Tanous #include <vector>
651da66f75SEd Tanous 
661da66f75SEd Tanous namespace redfish
671da66f75SEd Tanous {
681da66f75SEd Tanous 
6989492a15SPatrick Williams constexpr const char* crashdumpObject = "com.intel.crashdump";
7089492a15SPatrick Williams constexpr const char* crashdumpPath = "/com/intel/crashdump";
7189492a15SPatrick Williams constexpr const char* crashdumpInterface = "com.intel.crashdump";
7289492a15SPatrick Williams constexpr const char* deleteAllInterface =
735b61b5e8SJason M. Bills     "xyz.openbmc_project.Collection.DeleteAll";
7489492a15SPatrick Williams constexpr const char* crashdumpOnDemandInterface =
75424c4176SJason M. Bills     "com.intel.crashdump.OnDemand";
7689492a15SPatrick Williams constexpr const char* crashdumpTelemetryInterface =
776eda7685SKenny L. Ku     "com.intel.crashdump.Telemetry";
781da66f75SEd Tanous 
798e31778eSAsmitha Karunanithi enum class DumpCreationProgress
808e31778eSAsmitha Karunanithi {
818e31778eSAsmitha Karunanithi     DUMP_CREATE_SUCCESS,
828e31778eSAsmitha Karunanithi     DUMP_CREATE_FAILED,
838e31778eSAsmitha Karunanithi     DUMP_CREATE_INPROGRESS
848e31778eSAsmitha Karunanithi };
858e31778eSAsmitha Karunanithi 
86cb92c03bSAndrew Geissler inline std::string translateSeverityDbusToRedfish(const std::string& s)
87cb92c03bSAndrew Geissler {
88d4d25793SEd Tanous     if ((s == "xyz.openbmc_project.Logging.Entry.Level.Alert") ||
89d4d25793SEd Tanous         (s == "xyz.openbmc_project.Logging.Entry.Level.Critical") ||
90d4d25793SEd Tanous         (s == "xyz.openbmc_project.Logging.Entry.Level.Emergency") ||
91d4d25793SEd Tanous         (s == "xyz.openbmc_project.Logging.Entry.Level.Error"))
92cb92c03bSAndrew Geissler     {
93cb92c03bSAndrew Geissler         return "Critical";
94cb92c03bSAndrew Geissler     }
953174e4dfSEd Tanous     if ((s == "xyz.openbmc_project.Logging.Entry.Level.Debug") ||
96d4d25793SEd Tanous         (s == "xyz.openbmc_project.Logging.Entry.Level.Informational") ||
97d4d25793SEd Tanous         (s == "xyz.openbmc_project.Logging.Entry.Level.Notice"))
98cb92c03bSAndrew Geissler     {
99cb92c03bSAndrew Geissler         return "OK";
100cb92c03bSAndrew Geissler     }
1013174e4dfSEd Tanous     if (s == "xyz.openbmc_project.Logging.Entry.Level.Warning")
102cb92c03bSAndrew Geissler     {
103cb92c03bSAndrew Geissler         return "Warning";
104cb92c03bSAndrew Geissler     }
105cb92c03bSAndrew Geissler     return "";
106cb92c03bSAndrew Geissler }
107cb92c03bSAndrew Geissler 
1089017faf2SAbhishek Patel inline std::optional<bool> getProviderNotifyAction(const std::string& notify)
1099017faf2SAbhishek Patel {
1109017faf2SAbhishek Patel     std::optional<bool> notifyAction;
1119017faf2SAbhishek Patel     if (notify == "xyz.openbmc_project.Logging.Entry.Notify.Notify")
1129017faf2SAbhishek Patel     {
1139017faf2SAbhishek Patel         notifyAction = true;
1149017faf2SAbhishek Patel     }
1159017faf2SAbhishek Patel     else if (notify == "xyz.openbmc_project.Logging.Entry.Notify.Inhibit")
1169017faf2SAbhishek Patel     {
1179017faf2SAbhishek Patel         notifyAction = false;
1189017faf2SAbhishek Patel     }
1199017faf2SAbhishek Patel 
1209017faf2SAbhishek Patel     return notifyAction;
1219017faf2SAbhishek Patel }
1229017faf2SAbhishek Patel 
12318f8f608SEd Tanous inline std::string getDumpPath(std::string_view dumpType)
12418f8f608SEd Tanous {
12518f8f608SEd Tanous     std::string dbusDumpPath = "/xyz/openbmc_project/dump/";
12618f8f608SEd Tanous     std::ranges::transform(dumpType, std::back_inserter(dbusDumpPath),
12718f8f608SEd Tanous                            bmcweb::asciiToLower);
12818f8f608SEd Tanous 
12918f8f608SEd Tanous     return dbusDumpPath;
13018f8f608SEd Tanous }
13118f8f608SEd Tanous 
132504af5a0SPatrick Williams inline log_entry::OriginatorTypes mapDbusOriginatorTypeToRedfish(
133504af5a0SPatrick Williams     const std::string& originatorType)
13468dd075aSAsmitha Karunanithi {
13568dd075aSAsmitha Karunanithi     if (originatorType ==
13668dd075aSAsmitha Karunanithi         "xyz.openbmc_project.Common.OriginatedBy.OriginatorTypes.Client")
13768dd075aSAsmitha Karunanithi     {
13868dd075aSAsmitha Karunanithi         return log_entry::OriginatorTypes::Client;
13968dd075aSAsmitha Karunanithi     }
14068dd075aSAsmitha Karunanithi     if (originatorType ==
14168dd075aSAsmitha Karunanithi         "xyz.openbmc_project.Common.OriginatedBy.OriginatorTypes.Internal")
14268dd075aSAsmitha Karunanithi     {
14368dd075aSAsmitha Karunanithi         return log_entry::OriginatorTypes::Internal;
14468dd075aSAsmitha Karunanithi     }
14568dd075aSAsmitha Karunanithi     if (originatorType ==
14668dd075aSAsmitha Karunanithi         "xyz.openbmc_project.Common.OriginatedBy.OriginatorTypes.SupportingService")
14768dd075aSAsmitha Karunanithi     {
14868dd075aSAsmitha Karunanithi         return log_entry::OriginatorTypes::SupportingService;
14968dd075aSAsmitha Karunanithi     }
15068dd075aSAsmitha Karunanithi     return log_entry::OriginatorTypes::Invalid;
15168dd075aSAsmitha Karunanithi }
15268dd075aSAsmitha Karunanithi 
153aefe3786SClaire Weinan inline void parseDumpEntryFromDbusObject(
1542d613eb6SJiaqing Zhao     const dbus::utility::ManagedObjectType::value_type& object,
155c6fecdabSClaire Weinan     std::string& dumpStatus, uint64_t& size, uint64_t& timestampUs,
15668dd075aSAsmitha Karunanithi     std::string& originatorId, log_entry::OriginatorTypes& originatorType,
157aefe3786SClaire Weinan     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
158aefe3786SClaire Weinan {
159aefe3786SClaire Weinan     for (const auto& interfaceMap : object.second)
160aefe3786SClaire Weinan     {
161aefe3786SClaire Weinan         if (interfaceMap.first == "xyz.openbmc_project.Common.Progress")
162aefe3786SClaire Weinan         {
163aefe3786SClaire Weinan             for (const auto& propertyMap : interfaceMap.second)
164aefe3786SClaire Weinan             {
165aefe3786SClaire Weinan                 if (propertyMap.first == "Status")
166aefe3786SClaire Weinan                 {
167aefe3786SClaire Weinan                     const auto* status =
168aefe3786SClaire Weinan                         std::get_if<std::string>(&propertyMap.second);
169aefe3786SClaire Weinan                     if (status == nullptr)
170aefe3786SClaire Weinan                     {
171aefe3786SClaire Weinan                         messages::internalError(asyncResp->res);
172aefe3786SClaire Weinan                         break;
173aefe3786SClaire Weinan                     }
174aefe3786SClaire Weinan                     dumpStatus = *status;
175aefe3786SClaire Weinan                 }
176aefe3786SClaire Weinan             }
177aefe3786SClaire Weinan         }
178aefe3786SClaire Weinan         else if (interfaceMap.first == "xyz.openbmc_project.Dump.Entry")
179aefe3786SClaire Weinan         {
180aefe3786SClaire Weinan             for (const auto& propertyMap : interfaceMap.second)
181aefe3786SClaire Weinan             {
182aefe3786SClaire Weinan                 if (propertyMap.first == "Size")
183aefe3786SClaire Weinan                 {
184aefe3786SClaire Weinan                     const auto* sizePtr =
185aefe3786SClaire Weinan                         std::get_if<uint64_t>(&propertyMap.second);
186aefe3786SClaire Weinan                     if (sizePtr == nullptr)
187aefe3786SClaire Weinan                     {
188aefe3786SClaire Weinan                         messages::internalError(asyncResp->res);
189aefe3786SClaire Weinan                         break;
190aefe3786SClaire Weinan                     }
191aefe3786SClaire Weinan                     size = *sizePtr;
192aefe3786SClaire Weinan                     break;
193aefe3786SClaire Weinan                 }
194aefe3786SClaire Weinan             }
195aefe3786SClaire Weinan         }
196aefe3786SClaire Weinan         else if (interfaceMap.first == "xyz.openbmc_project.Time.EpochTime")
197aefe3786SClaire Weinan         {
198aefe3786SClaire Weinan             for (const auto& propertyMap : interfaceMap.second)
199aefe3786SClaire Weinan             {
200aefe3786SClaire Weinan                 if (propertyMap.first == "Elapsed")
201aefe3786SClaire Weinan                 {
202aefe3786SClaire Weinan                     const uint64_t* usecsTimeStamp =
203aefe3786SClaire Weinan                         std::get_if<uint64_t>(&propertyMap.second);
204aefe3786SClaire Weinan                     if (usecsTimeStamp == nullptr)
205aefe3786SClaire Weinan                     {
206aefe3786SClaire Weinan                         messages::internalError(asyncResp->res);
207aefe3786SClaire Weinan                         break;
208aefe3786SClaire Weinan                     }
209c6fecdabSClaire Weinan                     timestampUs = *usecsTimeStamp;
210aefe3786SClaire Weinan                     break;
211aefe3786SClaire Weinan                 }
212aefe3786SClaire Weinan             }
213aefe3786SClaire Weinan         }
21468dd075aSAsmitha Karunanithi         else if (interfaceMap.first ==
21568dd075aSAsmitha Karunanithi                  "xyz.openbmc_project.Common.OriginatedBy")
21668dd075aSAsmitha Karunanithi         {
21768dd075aSAsmitha Karunanithi             for (const auto& propertyMap : interfaceMap.second)
21868dd075aSAsmitha Karunanithi             {
21968dd075aSAsmitha Karunanithi                 if (propertyMap.first == "OriginatorId")
22068dd075aSAsmitha Karunanithi                 {
22168dd075aSAsmitha Karunanithi                     const std::string* id =
22268dd075aSAsmitha Karunanithi                         std::get_if<std::string>(&propertyMap.second);
22368dd075aSAsmitha Karunanithi                     if (id == nullptr)
22468dd075aSAsmitha Karunanithi                     {
22568dd075aSAsmitha Karunanithi                         messages::internalError(asyncResp->res);
22668dd075aSAsmitha Karunanithi                         break;
22768dd075aSAsmitha Karunanithi                     }
22868dd075aSAsmitha Karunanithi                     originatorId = *id;
22968dd075aSAsmitha Karunanithi                 }
23068dd075aSAsmitha Karunanithi 
23168dd075aSAsmitha Karunanithi                 if (propertyMap.first == "OriginatorType")
23268dd075aSAsmitha Karunanithi                 {
23368dd075aSAsmitha Karunanithi                     const std::string* type =
23468dd075aSAsmitha Karunanithi                         std::get_if<std::string>(&propertyMap.second);
23568dd075aSAsmitha Karunanithi                     if (type == nullptr)
23668dd075aSAsmitha Karunanithi                     {
23768dd075aSAsmitha Karunanithi                         messages::internalError(asyncResp->res);
23868dd075aSAsmitha Karunanithi                         break;
23968dd075aSAsmitha Karunanithi                     }
24068dd075aSAsmitha Karunanithi 
24168dd075aSAsmitha Karunanithi                     originatorType = mapDbusOriginatorTypeToRedfish(*type);
24268dd075aSAsmitha Karunanithi                     if (originatorType == log_entry::OriginatorTypes::Invalid)
24368dd075aSAsmitha Karunanithi                     {
24468dd075aSAsmitha Karunanithi                         messages::internalError(asyncResp->res);
24568dd075aSAsmitha Karunanithi                         break;
24668dd075aSAsmitha Karunanithi                     }
24768dd075aSAsmitha Karunanithi                 }
24868dd075aSAsmitha Karunanithi             }
24968dd075aSAsmitha Karunanithi         }
250aefe3786SClaire Weinan     }
251aefe3786SClaire Weinan }
252aefe3786SClaire Weinan 
25321ab404cSNan Zhou static std::string getDumpEntriesPath(const std::string& dumpType)
254fdd26906SClaire Weinan {
255fdd26906SClaire Weinan     std::string entriesPath;
256fdd26906SClaire Weinan 
257fdd26906SClaire Weinan     if (dumpType == "BMC")
258fdd26906SClaire Weinan     {
259253f11b8SEd Tanous         entriesPath =
260253f11b8SEd Tanous             std::format("/redfish/v1/Managers/{}/LogServices/Dump/Entries/",
261253f11b8SEd Tanous                         BMCWEB_REDFISH_MANAGER_URI_NAME);
262fdd26906SClaire Weinan     }
263fdd26906SClaire Weinan     else if (dumpType == "FaultLog")
264fdd26906SClaire Weinan     {
265253f11b8SEd Tanous         entriesPath =
266253f11b8SEd Tanous             std::format("/redfish/v1/Managers/{}/LogServices/FaultLog/Entries/",
267253f11b8SEd Tanous                         BMCWEB_REDFISH_MANAGER_URI_NAME);
268fdd26906SClaire Weinan     }
269fdd26906SClaire Weinan     else if (dumpType == "System")
270fdd26906SClaire Weinan     {
271253f11b8SEd Tanous         entriesPath =
272253f11b8SEd Tanous             std::format("/redfish/v1/Systems/{}/LogServices/Dump/Entries/",
273253f11b8SEd Tanous                         BMCWEB_REDFISH_SYSTEM_URI_NAME);
274fdd26906SClaire Weinan     }
275fdd26906SClaire Weinan     else
276fdd26906SClaire Weinan     {
27762598e31SEd Tanous         BMCWEB_LOG_ERROR("getDumpEntriesPath() invalid dump type: {}",
27862598e31SEd Tanous                          dumpType);
279fdd26906SClaire Weinan     }
280fdd26906SClaire Weinan 
281fdd26906SClaire Weinan     // Returns empty string on error
282fdd26906SClaire Weinan     return entriesPath;
283fdd26906SClaire Weinan }
284fdd26906SClaire Weinan 
285504af5a0SPatrick Williams inline void getDumpEntryCollection(
286504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2875cb1dd27SAsmitha Karunanithi     const std::string& dumpType)
2885cb1dd27SAsmitha Karunanithi {
289fdd26906SClaire Weinan     std::string entriesPath = getDumpEntriesPath(dumpType);
290fdd26906SClaire Weinan     if (entriesPath.empty())
2915cb1dd27SAsmitha Karunanithi     {
2925cb1dd27SAsmitha Karunanithi         messages::internalError(asyncResp->res);
2935cb1dd27SAsmitha Karunanithi         return;
2945cb1dd27SAsmitha Karunanithi     }
2955cb1dd27SAsmitha Karunanithi 
2965eb468daSGeorge Liu     sdbusplus::message::object_path path("/xyz/openbmc_project/dump");
2975eb468daSGeorge Liu     dbus::utility::getManagedObjects(
2985eb468daSGeorge Liu         "xyz.openbmc_project.Dump.Manager", path,
299fdd26906SClaire Weinan         [asyncResp, entriesPath,
3005e7e2dc5SEd Tanous          dumpType](const boost::system::error_code& ec,
3015eb468daSGeorge Liu                    const dbus::utility::ManagedObjectType& objects) {
3025cb1dd27SAsmitha Karunanithi             if (ec)
3035cb1dd27SAsmitha Karunanithi             {
30462598e31SEd Tanous                 BMCWEB_LOG_ERROR("DumpEntry resp_handler got error {}", ec);
3055cb1dd27SAsmitha Karunanithi                 messages::internalError(asyncResp->res);
3065cb1dd27SAsmitha Karunanithi                 return;
3075cb1dd27SAsmitha Karunanithi             }
3085cb1dd27SAsmitha Karunanithi 
309fdd26906SClaire Weinan             // Remove ending slash
310fdd26906SClaire Weinan             std::string odataIdStr = entriesPath;
311fdd26906SClaire Weinan             if (!odataIdStr.empty())
312fdd26906SClaire Weinan             {
313fdd26906SClaire Weinan                 odataIdStr.pop_back();
314fdd26906SClaire Weinan             }
315fdd26906SClaire Weinan 
316fdd26906SClaire Weinan             asyncResp->res.jsonValue["@odata.type"] =
317fdd26906SClaire Weinan                 "#LogEntryCollection.LogEntryCollection";
318fdd26906SClaire Weinan             asyncResp->res.jsonValue["@odata.id"] = std::move(odataIdStr);
319fdd26906SClaire Weinan             asyncResp->res.jsonValue["Name"] = dumpType + " Dump Entries";
320bd79bce8SPatrick Williams             asyncResp->res.jsonValue["Description"] =
321bd79bce8SPatrick Williams                 "Collection of " + dumpType + " Dump Entries";
322fdd26906SClaire Weinan 
3233544d2a7SEd Tanous             nlohmann::json::array_t entriesArray;
32418f8f608SEd Tanous             std::string dumpEntryPath = getDumpPath(dumpType) + "/entry/";
3255cb1dd27SAsmitha Karunanithi 
3265eb468daSGeorge Liu             dbus::utility::ManagedObjectType resp(objects);
3273544d2a7SEd Tanous             std::ranges::sort(resp, [](const auto& l, const auto& r) {
328002d39b4SEd Tanous                 return AlphanumLess<std::string>()(l.first.filename(),
329002d39b4SEd Tanous                                                    r.first.filename());
330565dfb6fSClaire Weinan             });
331565dfb6fSClaire Weinan 
3325cb1dd27SAsmitha Karunanithi             for (auto& object : resp)
3335cb1dd27SAsmitha Karunanithi             {
334b47452b2SAsmitha Karunanithi                 if (object.first.str.find(dumpEntryPath) == std::string::npos)
3355cb1dd27SAsmitha Karunanithi                 {
3365cb1dd27SAsmitha Karunanithi                     continue;
3375cb1dd27SAsmitha Karunanithi                 }
338c6fecdabSClaire Weinan                 uint64_t timestampUs = 0;
3395cb1dd27SAsmitha Karunanithi                 uint64_t size = 0;
34035440d18SAsmitha Karunanithi                 std::string dumpStatus;
34168dd075aSAsmitha Karunanithi                 std::string originatorId;
34268dd075aSAsmitha Karunanithi                 log_entry::OriginatorTypes originatorType =
34368dd075aSAsmitha Karunanithi                     log_entry::OriginatorTypes::Internal;
344433b68b4SJason M. Bills                 nlohmann::json::object_t thisEntry;
3452dfd18efSEd Tanous 
3462dfd18efSEd Tanous                 std::string entryID = object.first.filename();
3472dfd18efSEd Tanous                 if (entryID.empty())
3485cb1dd27SAsmitha Karunanithi                 {
3495cb1dd27SAsmitha Karunanithi                     continue;
3505cb1dd27SAsmitha Karunanithi                 }
3515cb1dd27SAsmitha Karunanithi 
352bd79bce8SPatrick Williams                 parseDumpEntryFromDbusObject(object, dumpStatus, size,
353bd79bce8SPatrick Williams                                              timestampUs, originatorId,
354bd79bce8SPatrick Williams                                              originatorType, asyncResp);
3555cb1dd27SAsmitha Karunanithi 
3560fda0f12SGeorge Liu                 if (dumpStatus !=
3570fda0f12SGeorge Liu                         "xyz.openbmc_project.Common.Progress.OperationStatus.Completed" &&
35835440d18SAsmitha Karunanithi                     !dumpStatus.empty())
35935440d18SAsmitha Karunanithi                 {
36035440d18SAsmitha Karunanithi                     // Dump status is not Complete, no need to enumerate
36135440d18SAsmitha Karunanithi                     continue;
36235440d18SAsmitha Karunanithi                 }
36335440d18SAsmitha Karunanithi 
36468dd075aSAsmitha Karunanithi                 thisEntry["@odata.type"] = "#LogEntry.v1_11_0.LogEntry";
365fdd26906SClaire Weinan                 thisEntry["@odata.id"] = entriesPath + entryID;
3665cb1dd27SAsmitha Karunanithi                 thisEntry["Id"] = entryID;
3675cb1dd27SAsmitha Karunanithi                 thisEntry["EntryType"] = "Event";
3685cb1dd27SAsmitha Karunanithi                 thisEntry["Name"] = dumpType + " Dump Entry";
369bbd80db8SClaire Weinan                 thisEntry["Created"] =
370bbd80db8SClaire Weinan                     redfish::time_utils::getDateTimeUintUs(timestampUs);
3715cb1dd27SAsmitha Karunanithi 
37268dd075aSAsmitha Karunanithi                 if (!originatorId.empty())
37368dd075aSAsmitha Karunanithi                 {
37468dd075aSAsmitha Karunanithi                     thisEntry["Originator"] = originatorId;
37568dd075aSAsmitha Karunanithi                     thisEntry["OriginatorType"] = originatorType;
37668dd075aSAsmitha Karunanithi                 }
37768dd075aSAsmitha Karunanithi 
3785cb1dd27SAsmitha Karunanithi                 if (dumpType == "BMC")
3795cb1dd27SAsmitha Karunanithi                 {
380d337bb72SAsmitha Karunanithi                     thisEntry["DiagnosticDataType"] = "Manager";
381bd79bce8SPatrick Williams                     thisEntry["AdditionalDataURI"] =
382bd79bce8SPatrick Williams                         entriesPath + entryID + "/attachment";
383fdd26906SClaire Weinan                     thisEntry["AdditionalDataSizeBytes"] = size;
3845cb1dd27SAsmitha Karunanithi                 }
3855cb1dd27SAsmitha Karunanithi                 else if (dumpType == "System")
3865cb1dd27SAsmitha Karunanithi                 {
387d337bb72SAsmitha Karunanithi                     thisEntry["DiagnosticDataType"] = "OEM";
388d337bb72SAsmitha Karunanithi                     thisEntry["OEMDiagnosticDataType"] = "System";
389bd79bce8SPatrick Williams                     thisEntry["AdditionalDataURI"] =
390bd79bce8SPatrick Williams                         entriesPath + entryID + "/attachment";
391fdd26906SClaire Weinan                     thisEntry["AdditionalDataSizeBytes"] = size;
3925cb1dd27SAsmitha Karunanithi                 }
393b2ba3072SPatrick Williams                 entriesArray.emplace_back(std::move(thisEntry));
3945cb1dd27SAsmitha Karunanithi             }
395bd79bce8SPatrick Williams             asyncResp->res.jsonValue["Members@odata.count"] =
396bd79bce8SPatrick Williams                 entriesArray.size();
3973544d2a7SEd Tanous             asyncResp->res.jsonValue["Members"] = std::move(entriesArray);
3985eb468daSGeorge Liu         });
3995cb1dd27SAsmitha Karunanithi }
4005cb1dd27SAsmitha Karunanithi 
401504af5a0SPatrick Williams inline void getDumpEntryById(
402504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
4038d1b46d7Szhanghch05     const std::string& entryID, const std::string& dumpType)
4045cb1dd27SAsmitha Karunanithi {
405fdd26906SClaire Weinan     std::string entriesPath = getDumpEntriesPath(dumpType);
406fdd26906SClaire Weinan     if (entriesPath.empty())
4075cb1dd27SAsmitha Karunanithi     {
4085cb1dd27SAsmitha Karunanithi         messages::internalError(asyncResp->res);
4095cb1dd27SAsmitha Karunanithi         return;
4105cb1dd27SAsmitha Karunanithi     }
4115cb1dd27SAsmitha Karunanithi 
4125eb468daSGeorge Liu     sdbusplus::message::object_path path("/xyz/openbmc_project/dump");
4135eb468daSGeorge Liu     dbus::utility::getManagedObjects(
4145eb468daSGeorge Liu         "xyz.openbmc_project.Dump.Manager", path,
415fdd26906SClaire Weinan         [asyncResp, entryID, dumpType,
4165e7e2dc5SEd Tanous          entriesPath](const boost::system::error_code& ec,
41702cad96eSEd Tanous                       const dbus::utility::ManagedObjectType& resp) {
4185cb1dd27SAsmitha Karunanithi             if (ec)
4195cb1dd27SAsmitha Karunanithi             {
42062598e31SEd Tanous                 BMCWEB_LOG_ERROR("DumpEntry resp_handler got error {}", ec);
4215cb1dd27SAsmitha Karunanithi                 messages::internalError(asyncResp->res);
4225cb1dd27SAsmitha Karunanithi                 return;
4235cb1dd27SAsmitha Karunanithi             }
4245cb1dd27SAsmitha Karunanithi 
425b47452b2SAsmitha Karunanithi             bool foundDumpEntry = false;
42618f8f608SEd Tanous             std::string dumpEntryPath = getDumpPath(dumpType) + "/entry/";
427b47452b2SAsmitha Karunanithi 
4289eb808c1SEd Tanous             for (const auto& objectPath : resp)
4295cb1dd27SAsmitha Karunanithi             {
430b47452b2SAsmitha Karunanithi                 if (objectPath.first.str != dumpEntryPath + entryID)
4315cb1dd27SAsmitha Karunanithi                 {
4325cb1dd27SAsmitha Karunanithi                     continue;
4335cb1dd27SAsmitha Karunanithi                 }
4345cb1dd27SAsmitha Karunanithi 
4355cb1dd27SAsmitha Karunanithi                 foundDumpEntry = true;
436c6fecdabSClaire Weinan                 uint64_t timestampUs = 0;
4375cb1dd27SAsmitha Karunanithi                 uint64_t size = 0;
43835440d18SAsmitha Karunanithi                 std::string dumpStatus;
43968dd075aSAsmitha Karunanithi                 std::string originatorId;
44068dd075aSAsmitha Karunanithi                 log_entry::OriginatorTypes originatorType =
44168dd075aSAsmitha Karunanithi                     log_entry::OriginatorTypes::Internal;
4425cb1dd27SAsmitha Karunanithi 
443aefe3786SClaire Weinan                 parseDumpEntryFromDbusObject(objectPath, dumpStatus, size,
44468dd075aSAsmitha Karunanithi                                              timestampUs, originatorId,
44568dd075aSAsmitha Karunanithi                                              originatorType, asyncResp);
4465cb1dd27SAsmitha Karunanithi 
4470fda0f12SGeorge Liu                 if (dumpStatus !=
4480fda0f12SGeorge Liu                         "xyz.openbmc_project.Common.Progress.OperationStatus.Completed" &&
44935440d18SAsmitha Karunanithi                     !dumpStatus.empty())
45035440d18SAsmitha Karunanithi                 {
45135440d18SAsmitha Karunanithi                     // Dump status is not Complete
45235440d18SAsmitha Karunanithi                     // return not found until status is changed to Completed
453bd79bce8SPatrick Williams                     messages::resourceNotFound(asyncResp->res,
454bd79bce8SPatrick Williams                                                dumpType + " dump", entryID);
45535440d18SAsmitha Karunanithi                     return;
45635440d18SAsmitha Karunanithi                 }
45735440d18SAsmitha Karunanithi 
4585cb1dd27SAsmitha Karunanithi                 asyncResp->res.jsonValue["@odata.type"] =
45968dd075aSAsmitha Karunanithi                     "#LogEntry.v1_11_0.LogEntry";
460fdd26906SClaire Weinan                 asyncResp->res.jsonValue["@odata.id"] = entriesPath + entryID;
4615cb1dd27SAsmitha Karunanithi                 asyncResp->res.jsonValue["Id"] = entryID;
4625cb1dd27SAsmitha Karunanithi                 asyncResp->res.jsonValue["EntryType"] = "Event";
4635cb1dd27SAsmitha Karunanithi                 asyncResp->res.jsonValue["Name"] = dumpType + " Dump Entry";
464bbd80db8SClaire Weinan                 asyncResp->res.jsonValue["Created"] =
465bbd80db8SClaire Weinan                     redfish::time_utils::getDateTimeUintUs(timestampUs);
4665cb1dd27SAsmitha Karunanithi 
46768dd075aSAsmitha Karunanithi                 if (!originatorId.empty())
46868dd075aSAsmitha Karunanithi                 {
46968dd075aSAsmitha Karunanithi                     asyncResp->res.jsonValue["Originator"] = originatorId;
47068dd075aSAsmitha Karunanithi                     asyncResp->res.jsonValue["OriginatorType"] = originatorType;
47168dd075aSAsmitha Karunanithi                 }
47268dd075aSAsmitha Karunanithi 
4735cb1dd27SAsmitha Karunanithi                 if (dumpType == "BMC")
4745cb1dd27SAsmitha Karunanithi                 {
475d337bb72SAsmitha Karunanithi                     asyncResp->res.jsonValue["DiagnosticDataType"] = "Manager";
476d337bb72SAsmitha Karunanithi                     asyncResp->res.jsonValue["AdditionalDataURI"] =
477fdd26906SClaire Weinan                         entriesPath + entryID + "/attachment";
478fdd26906SClaire Weinan                     asyncResp->res.jsonValue["AdditionalDataSizeBytes"] = size;
4795cb1dd27SAsmitha Karunanithi                 }
4805cb1dd27SAsmitha Karunanithi                 else if (dumpType == "System")
4815cb1dd27SAsmitha Karunanithi                 {
482d337bb72SAsmitha Karunanithi                     asyncResp->res.jsonValue["DiagnosticDataType"] = "OEM";
483bd79bce8SPatrick Williams                     asyncResp->res.jsonValue["OEMDiagnosticDataType"] =
484bd79bce8SPatrick Williams                         "System";
485d337bb72SAsmitha Karunanithi                     asyncResp->res.jsonValue["AdditionalDataURI"] =
486fdd26906SClaire Weinan                         entriesPath + entryID + "/attachment";
487fdd26906SClaire Weinan                     asyncResp->res.jsonValue["AdditionalDataSizeBytes"] = size;
4885cb1dd27SAsmitha Karunanithi                 }
4895cb1dd27SAsmitha Karunanithi             }
490e05aec50SEd Tanous             if (!foundDumpEntry)
491b47452b2SAsmitha Karunanithi             {
49262598e31SEd Tanous                 BMCWEB_LOG_WARNING("Can't find Dump Entry {}", entryID);
493b90d14f2SMyung Bae                 messages::resourceNotFound(asyncResp->res, dumpType + " dump",
494b90d14f2SMyung Bae                                            entryID);
495b47452b2SAsmitha Karunanithi                 return;
496b47452b2SAsmitha Karunanithi             }
4975eb468daSGeorge Liu         });
4985cb1dd27SAsmitha Karunanithi }
4995cb1dd27SAsmitha Karunanithi 
5008d1b46d7Szhanghch05 inline void deleteDumpEntry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
5019878256fSStanley Chu                             const std::string& entryID,
502b47452b2SAsmitha Karunanithi                             const std::string& dumpType)
5035cb1dd27SAsmitha Karunanithi {
5045a39f77aSPatrick Williams     auto respHandler = [asyncResp,
5055a39f77aSPatrick Williams                         entryID](const boost::system::error_code& ec) {
50662598e31SEd Tanous         BMCWEB_LOG_DEBUG("Dump Entry doDelete callback: Done");
5075cb1dd27SAsmitha Karunanithi         if (ec)
5085cb1dd27SAsmitha Karunanithi         {
5093de8d8baSGeorge Liu             if (ec.value() == EBADR)
5103de8d8baSGeorge Liu             {
5113de8d8baSGeorge Liu                 messages::resourceNotFound(asyncResp->res, "LogEntry", entryID);
5123de8d8baSGeorge Liu                 return;
5133de8d8baSGeorge Liu             }
51462598e31SEd Tanous             BMCWEB_LOG_ERROR(
51562598e31SEd Tanous                 "Dump (DBus) doDelete respHandler got error {} entryID={}", ec,
51662598e31SEd Tanous                 entryID);
5175cb1dd27SAsmitha Karunanithi             messages::internalError(asyncResp->res);
5185cb1dd27SAsmitha Karunanithi             return;
5195cb1dd27SAsmitha Karunanithi         }
5205cb1dd27SAsmitha Karunanithi     };
52118f8f608SEd Tanous 
522177612aaSEd Tanous     dbus::utility::async_method_call(
523177612aaSEd Tanous         asyncResp, respHandler, "xyz.openbmc_project.Dump.Manager",
52418f8f608SEd Tanous         std::format("{}/entry/{}", getDumpPath(dumpType), entryID),
5255cb1dd27SAsmitha Karunanithi         "xyz.openbmc_project.Object.Delete", "Delete");
5265cb1dd27SAsmitha Karunanithi }
527168d1b1aSCarson Labrado 
528504af5a0SPatrick Williams inline void downloadDumpEntry(
529504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
530168d1b1aSCarson Labrado     const std::string& entryID, const std::string& dumpType)
531168d1b1aSCarson Labrado {
532168d1b1aSCarson Labrado     if (dumpType != "BMC")
533168d1b1aSCarson Labrado     {
534168d1b1aSCarson Labrado         BMCWEB_LOG_WARNING("Can't find Dump Entry {}", entryID);
535168d1b1aSCarson Labrado         messages::resourceNotFound(asyncResp->res, dumpType + " dump", entryID);
536168d1b1aSCarson Labrado         return;
537168d1b1aSCarson Labrado     }
538168d1b1aSCarson Labrado 
539bd79bce8SPatrick Williams     std::string dumpEntryPath =
540bd79bce8SPatrick Williams         std::format("{}/entry/{}", getDumpPath(dumpType), entryID);
541168d1b1aSCarson Labrado 
542168d1b1aSCarson Labrado     auto downloadDumpEntryHandler =
543168d1b1aSCarson Labrado         [asyncResp, entryID,
544168d1b1aSCarson Labrado          dumpType](const boost::system::error_code& ec,
545168d1b1aSCarson Labrado                    const sdbusplus::message::unix_fd& unixfd) {
546ff35df94SOliver Brewka             log_services_utils::downloadEntryCallback(asyncResp, entryID,
547ff35df94SOliver Brewka                                                       dumpType, ec, unixfd);
548168d1b1aSCarson Labrado         };
549168d1b1aSCarson Labrado 
550177612aaSEd Tanous     dbus::utility::async_method_call(
551177612aaSEd Tanous         asyncResp, std::move(downloadDumpEntryHandler),
552177612aaSEd Tanous         "xyz.openbmc_project.Dump.Manager", dumpEntryPath,
553177612aaSEd Tanous         "xyz.openbmc_project.Dump.Entry", "GetFileHandle");
554168d1b1aSCarson Labrado }
555168d1b1aSCarson Labrado 
556bd79bce8SPatrick Williams inline void downloadEventLogEntry(
557bd79bce8SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
558bd79bce8SPatrick Williams     const std::string& systemName, const std::string& entryID,
559168d1b1aSCarson Labrado     const std::string& dumpType)
560168d1b1aSCarson Labrado {
56125b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
562168d1b1aSCarson Labrado     {
563168d1b1aSCarson Labrado         // Option currently returns no systems.  TBD
564168d1b1aSCarson Labrado         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
565168d1b1aSCarson Labrado                                    systemName);
566168d1b1aSCarson Labrado         return;
567168d1b1aSCarson Labrado     }
568253f11b8SEd Tanous     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
569168d1b1aSCarson Labrado     {
570168d1b1aSCarson Labrado         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
571168d1b1aSCarson Labrado                                    systemName);
572168d1b1aSCarson Labrado         return;
573168d1b1aSCarson Labrado     }
574168d1b1aSCarson Labrado 
575168d1b1aSCarson Labrado     std::string entryPath =
576168d1b1aSCarson Labrado         sdbusplus::message::object_path("/xyz/openbmc_project/logging/entry") /
577168d1b1aSCarson Labrado         entryID;
578168d1b1aSCarson Labrado 
579168d1b1aSCarson Labrado     auto downloadEventLogEntryHandler =
580168d1b1aSCarson Labrado         [asyncResp, entryID,
581168d1b1aSCarson Labrado          dumpType](const boost::system::error_code& ec,
582168d1b1aSCarson Labrado                    const sdbusplus::message::unix_fd& unixfd) {
583ff35df94SOliver Brewka             log_services_utils::downloadEntryCallback(asyncResp, entryID,
584ff35df94SOliver Brewka                                                       dumpType, ec, unixfd);
585168d1b1aSCarson Labrado         };
586168d1b1aSCarson Labrado 
587177612aaSEd Tanous     dbus::utility::async_method_call(
588177612aaSEd Tanous         asyncResp, std::move(downloadEventLogEntryHandler),
589177612aaSEd Tanous         "xyz.openbmc_project.Logging", entryPath,
590177612aaSEd Tanous         "xyz.openbmc_project.Logging.Entry", "GetEntry");
591168d1b1aSCarson Labrado }
592168d1b1aSCarson Labrado 
593504af5a0SPatrick Williams inline DumpCreationProgress mapDbusStatusToDumpProgress(
594504af5a0SPatrick Williams     const std::string& status)
595a43be80fSAsmitha Karunanithi {
5968e31778eSAsmitha Karunanithi     if (status ==
5978e31778eSAsmitha Karunanithi             "xyz.openbmc_project.Common.Progress.OperationStatus.Failed" ||
5988e31778eSAsmitha Karunanithi         status == "xyz.openbmc_project.Common.Progress.OperationStatus.Aborted")
5998e31778eSAsmitha Karunanithi     {
6008e31778eSAsmitha Karunanithi         return DumpCreationProgress::DUMP_CREATE_FAILED;
6018e31778eSAsmitha Karunanithi     }
6028e31778eSAsmitha Karunanithi     if (status ==
6038e31778eSAsmitha Karunanithi         "xyz.openbmc_project.Common.Progress.OperationStatus.Completed")
6048e31778eSAsmitha Karunanithi     {
6058e31778eSAsmitha Karunanithi         return DumpCreationProgress::DUMP_CREATE_SUCCESS;
6068e31778eSAsmitha Karunanithi     }
6078e31778eSAsmitha Karunanithi     return DumpCreationProgress::DUMP_CREATE_INPROGRESS;
6088e31778eSAsmitha Karunanithi }
6098e31778eSAsmitha Karunanithi 
610504af5a0SPatrick Williams inline DumpCreationProgress getDumpCompletionStatus(
611504af5a0SPatrick Williams     const dbus::utility::DBusPropertiesMap& values)
6128e31778eSAsmitha Karunanithi {
6138e31778eSAsmitha Karunanithi     for (const auto& [key, val] : values)
6148e31778eSAsmitha Karunanithi     {
6158e31778eSAsmitha Karunanithi         if (key == "Status")
6168e31778eSAsmitha Karunanithi         {
6178e31778eSAsmitha Karunanithi             const std::string* value = std::get_if<std::string>(&val);
6188e31778eSAsmitha Karunanithi             if (value == nullptr)
6198e31778eSAsmitha Karunanithi             {
62062598e31SEd Tanous                 BMCWEB_LOG_ERROR("Status property value is null");
6218e31778eSAsmitha Karunanithi                 return DumpCreationProgress::DUMP_CREATE_FAILED;
6228e31778eSAsmitha Karunanithi             }
6238e31778eSAsmitha Karunanithi             return mapDbusStatusToDumpProgress(*value);
6248e31778eSAsmitha Karunanithi         }
6258e31778eSAsmitha Karunanithi     }
6268e31778eSAsmitha Karunanithi     return DumpCreationProgress::DUMP_CREATE_INPROGRESS;
6278e31778eSAsmitha Karunanithi }
6288e31778eSAsmitha Karunanithi 
6298e31778eSAsmitha Karunanithi inline std::string getDumpEntryPath(const std::string& dumpPath)
6308e31778eSAsmitha Karunanithi {
6318e31778eSAsmitha Karunanithi     if (dumpPath == "/xyz/openbmc_project/dump/bmc/entry")
6328e31778eSAsmitha Karunanithi     {
633253f11b8SEd Tanous         return std::format("/redfish/v1/Managers/{}/LogServices/Dump/Entries/",
6349f565090SEd Tanous                            BMCWEB_REDFISH_MANAGER_URI_NAME);
6358e31778eSAsmitha Karunanithi     }
6368e31778eSAsmitha Karunanithi     if (dumpPath == "/xyz/openbmc_project/dump/system/entry")
6378e31778eSAsmitha Karunanithi     {
638253f11b8SEd Tanous         return std::format("/redfish/v1/Systems/{}/LogServices/Dump/Entries/",
639253f11b8SEd Tanous                            BMCWEB_REDFISH_SYSTEM_URI_NAME);
6408e31778eSAsmitha Karunanithi     }
6418e31778eSAsmitha Karunanithi     return "";
6428e31778eSAsmitha Karunanithi }
6438e31778eSAsmitha Karunanithi 
6448e31778eSAsmitha Karunanithi inline void createDumpTaskCallback(
6458e31778eSAsmitha Karunanithi     task::Payload&& payload,
6468e31778eSAsmitha Karunanithi     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
6478e31778eSAsmitha Karunanithi     const sdbusplus::message::object_path& createdObjPath)
6488e31778eSAsmitha Karunanithi {
6498e31778eSAsmitha Karunanithi     const std::string dumpPath = createdObjPath.parent_path().str;
6508e31778eSAsmitha Karunanithi     const std::string dumpId = createdObjPath.filename();
6518e31778eSAsmitha Karunanithi 
6528e31778eSAsmitha Karunanithi     std::string dumpEntryPath = getDumpEntryPath(dumpPath);
6538e31778eSAsmitha Karunanithi 
6548e31778eSAsmitha Karunanithi     if (dumpEntryPath.empty())
6558e31778eSAsmitha Karunanithi     {
65662598e31SEd Tanous         BMCWEB_LOG_ERROR("Invalid dump type received");
6578e31778eSAsmitha Karunanithi         messages::internalError(asyncResp->res);
6588e31778eSAsmitha Karunanithi         return;
6598e31778eSAsmitha Karunanithi     }
6608e31778eSAsmitha Karunanithi 
661177612aaSEd Tanous     dbus::utility::async_method_call(
662177612aaSEd Tanous         asyncResp,
6638cb2c024SEd Tanous         [asyncResp, payload = std::move(payload), createdObjPath,
6648e31778eSAsmitha Karunanithi          dumpEntryPath{std::move(dumpEntryPath)},
6655e7e2dc5SEd Tanous          dumpId](const boost::system::error_code& ec,
6668e31778eSAsmitha Karunanithi                  const std::string& introspectXml) {
6678e31778eSAsmitha Karunanithi             if (ec)
6688e31778eSAsmitha Karunanithi             {
66962598e31SEd Tanous                 BMCWEB_LOG_ERROR("Introspect call failed with error: {}",
67062598e31SEd Tanous                                  ec.message());
6718e31778eSAsmitha Karunanithi                 messages::internalError(asyncResp->res);
6728e31778eSAsmitha Karunanithi                 return;
6738e31778eSAsmitha Karunanithi             }
6748e31778eSAsmitha Karunanithi 
6758e31778eSAsmitha Karunanithi             // Check if the created dump object has implemented Progress
6768e31778eSAsmitha Karunanithi             // interface to track dump completion. If yes, fetch the "Status"
6778e31778eSAsmitha Karunanithi             // property of the interface, modify the task state accordingly.
6788e31778eSAsmitha Karunanithi             // Else, return task completed.
6798e31778eSAsmitha Karunanithi             tinyxml2::XMLDocument doc;
6808e31778eSAsmitha Karunanithi 
6818e31778eSAsmitha Karunanithi             doc.Parse(introspectXml.data(), introspectXml.size());
6828e31778eSAsmitha Karunanithi             tinyxml2::XMLNode* pRoot = doc.FirstChildElement("node");
6838e31778eSAsmitha Karunanithi             if (pRoot == nullptr)
6848e31778eSAsmitha Karunanithi             {
68562598e31SEd Tanous                 BMCWEB_LOG_ERROR("XML document failed to parse");
6868e31778eSAsmitha Karunanithi                 messages::internalError(asyncResp->res);
6878e31778eSAsmitha Karunanithi                 return;
6888e31778eSAsmitha Karunanithi             }
6898e31778eSAsmitha Karunanithi             tinyxml2::XMLElement* interfaceNode =
6908e31778eSAsmitha Karunanithi                 pRoot->FirstChildElement("interface");
6918e31778eSAsmitha Karunanithi 
6928e31778eSAsmitha Karunanithi             bool isProgressIntfPresent = false;
6938e31778eSAsmitha Karunanithi             while (interfaceNode != nullptr)
6948e31778eSAsmitha Karunanithi             {
695bd79bce8SPatrick Williams                 const char* thisInterfaceName =
696bd79bce8SPatrick Williams                     interfaceNode->Attribute("name");
6978e31778eSAsmitha Karunanithi                 if (thisInterfaceName != nullptr)
6988e31778eSAsmitha Karunanithi                 {
6998e31778eSAsmitha Karunanithi                     if (thisInterfaceName ==
7008e31778eSAsmitha Karunanithi                         std::string_view("xyz.openbmc_project.Common.Progress"))
7018e31778eSAsmitha Karunanithi                     {
7028e31778eSAsmitha Karunanithi                         interfaceNode =
7038e31778eSAsmitha Karunanithi                             interfaceNode->NextSiblingElement("interface");
7048e31778eSAsmitha Karunanithi                         continue;
7058e31778eSAsmitha Karunanithi                     }
7068e31778eSAsmitha Karunanithi                     isProgressIntfPresent = true;
7078e31778eSAsmitha Karunanithi                     break;
7088e31778eSAsmitha Karunanithi                 }
7098e31778eSAsmitha Karunanithi                 interfaceNode = interfaceNode->NextSiblingElement("interface");
7108e31778eSAsmitha Karunanithi             }
7118e31778eSAsmitha Karunanithi 
712a43be80fSAsmitha Karunanithi             std::shared_ptr<task::TaskData> task = task::TaskData::createTask(
7138e31778eSAsmitha Karunanithi                 [createdObjPath, dumpEntryPath, dumpId, isProgressIntfPresent](
714bd79bce8SPatrick Williams                     const boost::system::error_code& ec2,
715bd79bce8SPatrick Williams                     sdbusplus::message_t& msg,
716a43be80fSAsmitha Karunanithi                     const std::shared_ptr<task::TaskData>& taskData) {
7178b24275dSEd Tanous                     if (ec2)
718cb13a392SEd Tanous                     {
71962598e31SEd Tanous                         BMCWEB_LOG_ERROR("{}: Error in creating dump",
72062598e31SEd Tanous                                          createdObjPath.str);
721bd79bce8SPatrick Williams                         taskData->messages.emplace_back(
722bd79bce8SPatrick Williams                             messages::internalError());
7236145ed6fSAsmitha Karunanithi                         taskData->state = "Cancelled";
7246145ed6fSAsmitha Karunanithi                         return task::completed;
725cb13a392SEd Tanous                     }
726b9d36b47SEd Tanous 
7278e31778eSAsmitha Karunanithi                     if (isProgressIntfPresent)
728a43be80fSAsmitha Karunanithi                     {
7298e31778eSAsmitha Karunanithi                         dbus::utility::DBusPropertiesMap values;
7308e31778eSAsmitha Karunanithi                         std::string prop;
7318e31778eSAsmitha Karunanithi                         msg.read(prop, values);
7328e31778eSAsmitha Karunanithi 
7338e31778eSAsmitha Karunanithi                         DumpCreationProgress dumpStatus =
7348e31778eSAsmitha Karunanithi                             getDumpCompletionStatus(values);
735bd79bce8SPatrick Williams                         if (dumpStatus ==
736bd79bce8SPatrick Williams                             DumpCreationProgress::DUMP_CREATE_FAILED)
7378e31778eSAsmitha Karunanithi                         {
73862598e31SEd Tanous                             BMCWEB_LOG_ERROR("{}: Error in creating dump",
73962598e31SEd Tanous                                              createdObjPath.str);
7408e31778eSAsmitha Karunanithi                             taskData->state = "Cancelled";
7418e31778eSAsmitha Karunanithi                             return task::completed;
7428e31778eSAsmitha Karunanithi                         }
7438e31778eSAsmitha Karunanithi 
744bd79bce8SPatrick Williams                         if (dumpStatus ==
745bd79bce8SPatrick Williams                             DumpCreationProgress::DUMP_CREATE_INPROGRESS)
7468e31778eSAsmitha Karunanithi                         {
747bd79bce8SPatrick Williams                             BMCWEB_LOG_DEBUG(
748bd79bce8SPatrick Williams                                 "{}: Dump creation task is in progress",
74962598e31SEd Tanous                                 createdObjPath.str);
7508e31778eSAsmitha Karunanithi                             return !task::completed;
7518e31778eSAsmitha Karunanithi                         }
7528e31778eSAsmitha Karunanithi                     }
7538e31778eSAsmitha Karunanithi 
754a43be80fSAsmitha Karunanithi                     nlohmann::json retMessage = messages::success();
755a43be80fSAsmitha Karunanithi                     taskData->messages.emplace_back(retMessage);
756a43be80fSAsmitha Karunanithi 
757c51a58eeSEd Tanous                     boost::urls::url url = boost::urls::format(
758253f11b8SEd Tanous                         "/redfish/v1/Managers/{}/LogServices/Dump/Entries/{}",
759253f11b8SEd Tanous                         BMCWEB_REDFISH_MANAGER_URI_NAME, dumpId);
760c51a58eeSEd Tanous 
761c51a58eeSEd Tanous                     std::string headerLoc = "Location: ";
762c51a58eeSEd Tanous                     headerLoc += url.buffer();
763c51a58eeSEd Tanous 
764bd79bce8SPatrick Williams                     taskData->payload->httpHeaders.emplace_back(
765bd79bce8SPatrick Williams                         std::move(headerLoc));
766a43be80fSAsmitha Karunanithi 
76762598e31SEd Tanous                     BMCWEB_LOG_DEBUG("{}: Dump creation task completed",
76862598e31SEd Tanous                                      createdObjPath.str);
769a43be80fSAsmitha Karunanithi                     taskData->state = "Completed";
770b47452b2SAsmitha Karunanithi                     return task::completed;
771a43be80fSAsmitha Karunanithi                 },
7728e31778eSAsmitha Karunanithi                 "type='signal',interface='org.freedesktop.DBus.Properties',"
7738e31778eSAsmitha Karunanithi                 "member='PropertiesChanged',path='" +
7748e31778eSAsmitha Karunanithi                     createdObjPath.str + "'");
775a43be80fSAsmitha Karunanithi 
7768e31778eSAsmitha Karunanithi             // The task timer is set to max time limit within which the
7778e31778eSAsmitha Karunanithi             // requested dump will be collected.
7788e31778eSAsmitha Karunanithi             task->startTimer(std::chrono::minutes(6));
7798e31778eSAsmitha Karunanithi             task->payload.emplace(payload);
78029e2bdd7SChinmay Shripad Hegde             task->populateResp(asyncResp->res);
7818e31778eSAsmitha Karunanithi         },
7828e31778eSAsmitha Karunanithi         "xyz.openbmc_project.Dump.Manager", createdObjPath,
7838e31778eSAsmitha Karunanithi         "org.freedesktop.DBus.Introspectable", "Introspect");
784a43be80fSAsmitha Karunanithi }
785a43be80fSAsmitha Karunanithi 
7868d1b46d7Szhanghch05 inline void createDump(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
7878d1b46d7Szhanghch05                        const crow::Request& req, const std::string& dumpType)
788a43be80fSAsmitha Karunanithi {
789fdd26906SClaire Weinan     std::string dumpPath = getDumpEntriesPath(dumpType);
790fdd26906SClaire Weinan     if (dumpPath.empty())
791a43be80fSAsmitha Karunanithi     {
792a43be80fSAsmitha Karunanithi         messages::internalError(asyncResp->res);
793a43be80fSAsmitha Karunanithi         return;
794a43be80fSAsmitha Karunanithi     }
795a43be80fSAsmitha Karunanithi 
796a43be80fSAsmitha Karunanithi     std::optional<std::string> diagnosticDataType;
797a43be80fSAsmitha Karunanithi     std::optional<std::string> oemDiagnosticDataType;
798a43be80fSAsmitha Karunanithi 
799afc474aeSMyung Bae     if (!redfish::json_util::readJsonAction(               //
800afc474aeSMyung Bae             req, asyncResp->res,                           //
801afc474aeSMyung Bae             "DiagnosticDataType", diagnosticDataType,      //
802afc474aeSMyung Bae             "OEMDiagnosticDataType", oemDiagnosticDataType //
803afc474aeSMyung Bae             ))
804a43be80fSAsmitha Karunanithi     {
805a43be80fSAsmitha Karunanithi         return;
806a43be80fSAsmitha Karunanithi     }
807a43be80fSAsmitha Karunanithi 
808a43be80fSAsmitha Karunanithi     if (dumpType == "System")
809a43be80fSAsmitha Karunanithi     {
810a43be80fSAsmitha Karunanithi         if (!oemDiagnosticDataType || !diagnosticDataType)
811a43be80fSAsmitha Karunanithi         {
81262598e31SEd Tanous             BMCWEB_LOG_ERROR(
81362598e31SEd Tanous                 "CreateDump action parameter 'DiagnosticDataType'/'OEMDiagnosticDataType' value not found!");
814a43be80fSAsmitha Karunanithi             messages::actionParameterMissing(
815a43be80fSAsmitha Karunanithi                 asyncResp->res, "CollectDiagnosticData",
816a43be80fSAsmitha Karunanithi                 "DiagnosticDataType & OEMDiagnosticDataType");
817a43be80fSAsmitha Karunanithi             return;
818a43be80fSAsmitha Karunanithi         }
8193174e4dfSEd Tanous         if ((*oemDiagnosticDataType != "System") ||
820a43be80fSAsmitha Karunanithi             (*diagnosticDataType != "OEM"))
821a43be80fSAsmitha Karunanithi         {
82262598e31SEd Tanous             BMCWEB_LOG_ERROR("Wrong parameter values passed");
823ace85d60SEd Tanous             messages::internalError(asyncResp->res);
824a43be80fSAsmitha Karunanithi             return;
825a43be80fSAsmitha Karunanithi         }
826253f11b8SEd Tanous         dumpPath = std::format("/redfish/v1/Systems/{}/LogServices/Dump/",
827253f11b8SEd Tanous                                BMCWEB_REDFISH_SYSTEM_URI_NAME);
828a43be80fSAsmitha Karunanithi     }
829a43be80fSAsmitha Karunanithi     else if (dumpType == "BMC")
830a43be80fSAsmitha Karunanithi     {
831a43be80fSAsmitha Karunanithi         if (!diagnosticDataType)
832a43be80fSAsmitha Karunanithi         {
83362598e31SEd Tanous             BMCWEB_LOG_ERROR(
83462598e31SEd Tanous                 "CreateDump action parameter 'DiagnosticDataType' not found!");
835a43be80fSAsmitha Karunanithi             messages::actionParameterMissing(
836a43be80fSAsmitha Karunanithi                 asyncResp->res, "CollectDiagnosticData", "DiagnosticDataType");
837a43be80fSAsmitha Karunanithi             return;
838a43be80fSAsmitha Karunanithi         }
8393174e4dfSEd Tanous         if (*diagnosticDataType != "Manager")
840a43be80fSAsmitha Karunanithi         {
84162598e31SEd Tanous             BMCWEB_LOG_ERROR(
84262598e31SEd Tanous                 "Wrong parameter value passed for 'DiagnosticDataType'");
843ace85d60SEd Tanous             messages::internalError(asyncResp->res);
844a43be80fSAsmitha Karunanithi             return;
845a43be80fSAsmitha Karunanithi         }
846253f11b8SEd Tanous         dumpPath = std::format("/redfish/v1/Managers/{}/LogServices/Dump/",
847253f11b8SEd Tanous                                BMCWEB_REDFISH_MANAGER_URI_NAME);
8485907571dSAsmitha Karunanithi     }
8495907571dSAsmitha Karunanithi     else
8505907571dSAsmitha Karunanithi     {
85162598e31SEd Tanous         BMCWEB_LOG_ERROR("CreateDump failed. Unknown dump type");
8525907571dSAsmitha Karunanithi         messages::internalError(asyncResp->res);
8535907571dSAsmitha Karunanithi         return;
854a43be80fSAsmitha Karunanithi     }
855a43be80fSAsmitha Karunanithi 
8568e31778eSAsmitha Karunanithi     std::vector<std::pair<std::string, std::variant<std::string, uint64_t>>>
8578e31778eSAsmitha Karunanithi         createDumpParamVec;
8588e31778eSAsmitha Karunanithi 
859f574a8e1SCarson Labrado     if (req.session != nullptr)
860f574a8e1SCarson Labrado     {
86168dd075aSAsmitha Karunanithi         createDumpParamVec.emplace_back(
86268dd075aSAsmitha Karunanithi             "xyz.openbmc_project.Dump.Create.CreateParameters.OriginatorId",
86368dd075aSAsmitha Karunanithi             req.session->clientIp);
86468dd075aSAsmitha Karunanithi         createDumpParamVec.emplace_back(
86568dd075aSAsmitha Karunanithi             "xyz.openbmc_project.Dump.Create.CreateParameters.OriginatorType",
86668dd075aSAsmitha Karunanithi             "xyz.openbmc_project.Common.OriginatedBy.OriginatorTypes.Client");
867f574a8e1SCarson Labrado     }
86868dd075aSAsmitha Karunanithi 
869177612aaSEd Tanous     dbus::utility::async_method_call(
870177612aaSEd Tanous         asyncResp,
8715e7e2dc5SEd Tanous         [asyncResp, payload(task::Payload(req)),
8725e7e2dc5SEd Tanous          dumpPath](const boost::system::error_code& ec,
8735e7e2dc5SEd Tanous                    const sdbusplus::message_t& msg,
8748e31778eSAsmitha Karunanithi                    const sdbusplus::message::object_path& objPath) mutable {
875a43be80fSAsmitha Karunanithi             if (ec)
876a43be80fSAsmitha Karunanithi             {
87762598e31SEd Tanous                 BMCWEB_LOG_ERROR("CreateDump resp_handler got error {}", ec);
8785907571dSAsmitha Karunanithi                 const sd_bus_error* dbusError = msg.get_error();
8795907571dSAsmitha Karunanithi                 if (dbusError == nullptr)
8805907571dSAsmitha Karunanithi                 {
8815907571dSAsmitha Karunanithi                     messages::internalError(asyncResp->res);
8825907571dSAsmitha Karunanithi                     return;
8835907571dSAsmitha Karunanithi                 }
8845907571dSAsmitha Karunanithi 
88562598e31SEd Tanous                 BMCWEB_LOG_ERROR("CreateDump DBus error: {} and error msg: {}",
88662598e31SEd Tanous                                  dbusError->name, dbusError->message);
8875907571dSAsmitha Karunanithi                 if (std::string_view(
8885907571dSAsmitha Karunanithi                         "xyz.openbmc_project.Common.Error.NotAllowed") ==
8895907571dSAsmitha Karunanithi                     dbusError->name)
8905907571dSAsmitha Karunanithi                 {
8915907571dSAsmitha Karunanithi                     messages::resourceInStandby(asyncResp->res);
8925907571dSAsmitha Karunanithi                     return;
8935907571dSAsmitha Karunanithi                 }
8945907571dSAsmitha Karunanithi                 if (std::string_view(
8955907571dSAsmitha Karunanithi                         "xyz.openbmc_project.Dump.Create.Error.Disabled") ==
8965907571dSAsmitha Karunanithi                     dbusError->name)
8975907571dSAsmitha Karunanithi                 {
8985907571dSAsmitha Karunanithi                     messages::serviceDisabled(asyncResp->res, dumpPath);
8995907571dSAsmitha Karunanithi                     return;
9005907571dSAsmitha Karunanithi                 }
9015907571dSAsmitha Karunanithi                 if (std::string_view(
9025907571dSAsmitha Karunanithi                         "xyz.openbmc_project.Common.Error.Unavailable") ==
9035907571dSAsmitha Karunanithi                     dbusError->name)
9045907571dSAsmitha Karunanithi                 {
9055907571dSAsmitha Karunanithi                     messages::resourceInUse(asyncResp->res);
9065907571dSAsmitha Karunanithi                     return;
9075907571dSAsmitha Karunanithi                 }
9085907571dSAsmitha Karunanithi                 // Other Dbus errors such as:
9095907571dSAsmitha Karunanithi                 // xyz.openbmc_project.Common.Error.InvalidArgument &
9105907571dSAsmitha Karunanithi                 // org.freedesktop.DBus.Error.InvalidArgs are all related to
9115907571dSAsmitha Karunanithi                 // the dbus call that is made here in the bmcweb
9125907571dSAsmitha Karunanithi                 // implementation and has nothing to do with the client's
9135907571dSAsmitha Karunanithi                 // input in the request. Hence, returning internal error
9145907571dSAsmitha Karunanithi                 // back to the client.
915a43be80fSAsmitha Karunanithi                 messages::internalError(asyncResp->res);
916a43be80fSAsmitha Karunanithi                 return;
917a43be80fSAsmitha Karunanithi             }
91862598e31SEd Tanous             BMCWEB_LOG_DEBUG("Dump Created. Path: {}", objPath.str);
9198e31778eSAsmitha Karunanithi             createDumpTaskCallback(std::move(payload), asyncResp, objPath);
920a43be80fSAsmitha Karunanithi         },
92118f8f608SEd Tanous         "xyz.openbmc_project.Dump.Manager", getDumpPath(dumpType),
9228e31778eSAsmitha Karunanithi         "xyz.openbmc_project.Dump.Create", "CreateDump", createDumpParamVec);
923a43be80fSAsmitha Karunanithi }
924a43be80fSAsmitha Karunanithi 
9258d1b46d7Szhanghch05 inline void clearDump(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
9268d1b46d7Szhanghch05                       const std::string& dumpType)
92780319af1SAsmitha Karunanithi {
928177612aaSEd Tanous     dbus::utility::async_method_call(
929177612aaSEd Tanous         asyncResp,
9300d946211SClaire Weinan         [asyncResp](const boost::system::error_code& ec) {
93180319af1SAsmitha Karunanithi             if (ec)
93280319af1SAsmitha Karunanithi             {
93362598e31SEd Tanous                 BMCWEB_LOG_ERROR("clearDump resp_handler got error {}", ec);
93480319af1SAsmitha Karunanithi                 messages::internalError(asyncResp->res);
93580319af1SAsmitha Karunanithi                 return;
93680319af1SAsmitha Karunanithi             }
937e2460466SAmy Chang             messages::success(asyncResp->res);
9380d946211SClaire Weinan         },
93918f8f608SEd Tanous         "xyz.openbmc_project.Dump.Manager", getDumpPath(dumpType),
9400d946211SClaire Weinan         "xyz.openbmc_project.Collection.DeleteAll", "DeleteAll");
94180319af1SAsmitha Karunanithi }
94280319af1SAsmitha Karunanithi 
943bd79bce8SPatrick Williams inline void parseCrashdumpParameters(
944bd79bce8SPatrick Williams     const dbus::utility::DBusPropertiesMap& params, std::string& filename,
945bd79bce8SPatrick Williams     std::string& timestamp, std::string& logfile)
946043a0536SJohnathan Mantey {
947d1bde9e5SKrzysztof Grobelny     const std::string* filenamePtr = nullptr;
948d1bde9e5SKrzysztof Grobelny     const std::string* timestampPtr = nullptr;
949d1bde9e5SKrzysztof Grobelny     const std::string* logfilePtr = nullptr;
950d1bde9e5SKrzysztof Grobelny 
951d1bde9e5SKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
952d1bde9e5SKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), params, "Timestamp", timestampPtr,
953d1bde9e5SKrzysztof Grobelny         "Filename", filenamePtr, "Log", logfilePtr);
954d1bde9e5SKrzysztof Grobelny 
955d1bde9e5SKrzysztof Grobelny     if (!success)
956043a0536SJohnathan Mantey     {
957d1bde9e5SKrzysztof Grobelny         return;
958043a0536SJohnathan Mantey     }
959d1bde9e5SKrzysztof Grobelny 
960d1bde9e5SKrzysztof Grobelny     if (filenamePtr != nullptr)
961043a0536SJohnathan Mantey     {
962d1bde9e5SKrzysztof Grobelny         filename = *filenamePtr;
963d1bde9e5SKrzysztof Grobelny     }
964d1bde9e5SKrzysztof Grobelny 
965d1bde9e5SKrzysztof Grobelny     if (timestampPtr != nullptr)
966043a0536SJohnathan Mantey     {
967d1bde9e5SKrzysztof Grobelny         timestamp = *timestampPtr;
968043a0536SJohnathan Mantey     }
969d1bde9e5SKrzysztof Grobelny 
970d1bde9e5SKrzysztof Grobelny     if (logfilePtr != nullptr)
971043a0536SJohnathan Mantey     {
972d1bde9e5SKrzysztof Grobelny         logfile = *logfilePtr;
973043a0536SJohnathan Mantey     }
974043a0536SJohnathan Mantey }
975043a0536SJohnathan Mantey 
9767e860f15SJohn Edward Broadbent inline void requestRoutesSystemLogServiceCollection(App& app)
9771da66f75SEd Tanous {
978c4bf6374SJason M. Bills     /**
979c4bf6374SJason M. Bills      * Functions triggers appropriate requests on DBus
980c4bf6374SJason M. Bills      */
98122d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/")
982ed398213SEd Tanous         .privileges(redfish::privileges::getLogServiceCollection)
983bd79bce8SPatrick Williams         .methods(
984bd79bce8SPatrick Williams             boost::beast::http::verb::
985bd79bce8SPatrick Williams                 get)([&app](const crow::Request& req,
98622d268cbSEd Tanous                             const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
98722d268cbSEd Tanous                             const std::string& systemName) {
9883ba00073SCarson Labrado             if (!redfish::setUpRedfishRoute(app, req, asyncResp))
989c4bf6374SJason M. Bills             {
99045ca1b86SEd Tanous                 return;
99145ca1b86SEd Tanous             }
99225b54dbaSEd Tanous             if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
9937f3e84a1SEd Tanous             {
9947f3e84a1SEd Tanous                 // Option currently returns no systems.  TBD
9957f3e84a1SEd Tanous                 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
9967f3e84a1SEd Tanous                                            systemName);
9977f3e84a1SEd Tanous                 return;
9987f3e84a1SEd Tanous             }
999253f11b8SEd Tanous             if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
100022d268cbSEd Tanous             {
100122d268cbSEd Tanous                 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
100222d268cbSEd Tanous                                            systemName);
100322d268cbSEd Tanous                 return;
100422d268cbSEd Tanous             }
100522d268cbSEd Tanous 
10067e860f15SJohn Edward Broadbent             // Collections don't include the static data added by SubRoute
10077e860f15SJohn Edward Broadbent             // because it has a duplicate entry for members
1008c4bf6374SJason M. Bills             asyncResp->res.jsonValue["@odata.type"] =
1009c4bf6374SJason M. Bills                 "#LogServiceCollection.LogServiceCollection";
1010c4bf6374SJason M. Bills             asyncResp->res.jsonValue["@odata.id"] =
1011253f11b8SEd Tanous                 std::format("/redfish/v1/Systems/{}/LogServices",
1012253f11b8SEd Tanous                             BMCWEB_REDFISH_SYSTEM_URI_NAME);
101345ca1b86SEd Tanous             asyncResp->res.jsonValue["Name"] = "System Log Services Collection";
1014c4bf6374SJason M. Bills             asyncResp->res.jsonValue["Description"] =
1015c4bf6374SJason M. Bills                 "Collection of LogServices for this Computer System";
1016bd79bce8SPatrick Williams             nlohmann::json& logServiceArray =
1017bd79bce8SPatrick Williams                 asyncResp->res.jsonValue["Members"];
1018c4bf6374SJason M. Bills             logServiceArray = nlohmann::json::array();
10191476687dSEd Tanous             nlohmann::json::object_t eventLog;
10201476687dSEd Tanous             eventLog["@odata.id"] =
1021253f11b8SEd Tanous                 std::format("/redfish/v1/Systems/{}/LogServices/EventLog",
1022253f11b8SEd Tanous                             BMCWEB_REDFISH_SYSTEM_URI_NAME);
1023b2ba3072SPatrick Williams             logServiceArray.emplace_back(std::move(eventLog));
102425b54dbaSEd Tanous             if constexpr (BMCWEB_REDFISH_DUMP_LOG)
102525b54dbaSEd Tanous             {
10261476687dSEd Tanous                 nlohmann::json::object_t dumpLog;
102725b54dbaSEd Tanous                 dumpLog["@odata.id"] =
1028253f11b8SEd Tanous                     std::format("/redfish/v1/Systems/{}/LogServices/Dump",
1029253f11b8SEd Tanous                                 BMCWEB_REDFISH_SYSTEM_URI_NAME);
1030b2ba3072SPatrick Williams                 logServiceArray.emplace_back(std::move(dumpLog));
103125b54dbaSEd Tanous             }
1032c9bb6861Sraviteja-b 
10335ffd11f2SGunnar Mills             if constexpr (BMCWEB_REDFISH_CPU_LOG)
103425b54dbaSEd Tanous             {
10351476687dSEd Tanous                 nlohmann::json::object_t crashdump;
10361476687dSEd Tanous                 crashdump["@odata.id"] =
1037253f11b8SEd Tanous                     std::format("/redfish/v1/Systems/{}/LogServices/Crashdump",
1038253f11b8SEd Tanous                                 BMCWEB_REDFISH_SYSTEM_URI_NAME);
1039b2ba3072SPatrick Williams                 logServiceArray.emplace_back(std::move(crashdump));
104025b54dbaSEd Tanous             }
1041b7028ebfSSpencer Ku 
104225b54dbaSEd Tanous             if constexpr (BMCWEB_REDFISH_HOST_LOGGER)
104325b54dbaSEd Tanous             {
10441476687dSEd Tanous                 nlohmann::json::object_t hostlogger;
10451476687dSEd Tanous                 hostlogger["@odata.id"] =
1046253f11b8SEd Tanous                     std::format("/redfish/v1/Systems/{}/LogServices/HostLogger",
1047253f11b8SEd Tanous                                 BMCWEB_REDFISH_SYSTEM_URI_NAME);
1048b2ba3072SPatrick Williams                 logServiceArray.emplace_back(std::move(hostlogger));
104925b54dbaSEd Tanous             }
1050c4bf6374SJason M. Bills             asyncResp->res.jsonValue["Members@odata.count"] =
1051c4bf6374SJason M. Bills                 logServiceArray.size();
1052a3316fc6SZhikuiRen 
10537a1dbc48SGeorge Liu             constexpr std::array<std::string_view, 1> interfaces = {
10547a1dbc48SGeorge Liu                 "xyz.openbmc_project.State.Boot.PostCode"};
10557a1dbc48SGeorge Liu             dbus::utility::getSubTreePaths(
10567a1dbc48SGeorge Liu                 "/", 0, interfaces,
10577a1dbc48SGeorge Liu                 [asyncResp](const boost::system::error_code& ec,
1058b9d36b47SEd Tanous                             const dbus::utility::MapperGetSubTreePathsResponse&
1059b9d36b47SEd Tanous                                 subtreePath) {
1060a3316fc6SZhikuiRen                     if (ec)
1061a3316fc6SZhikuiRen                     {
106262598e31SEd Tanous                         BMCWEB_LOG_ERROR("{}", ec);
1063a3316fc6SZhikuiRen                         return;
1064a3316fc6SZhikuiRen                     }
1065a3316fc6SZhikuiRen 
106655f79e6fSEd Tanous                     for (const auto& pathStr : subtreePath)
1067a3316fc6SZhikuiRen                     {
1068a3316fc6SZhikuiRen                         if (pathStr.find("PostCode") != std::string::npos)
1069a3316fc6SZhikuiRen                         {
107023a21a1cSEd Tanous                             nlohmann::json& logServiceArrayLocal =
1071a3316fc6SZhikuiRen                                 asyncResp->res.jsonValue["Members"];
1072613dabeaSEd Tanous                             nlohmann::json::object_t member;
1073253f11b8SEd Tanous                             member["@odata.id"] = std::format(
1074253f11b8SEd Tanous                                 "/redfish/v1/Systems/{}/LogServices/PostCodes",
1075253f11b8SEd Tanous                                 BMCWEB_REDFISH_SYSTEM_URI_NAME);
1076613dabeaSEd Tanous 
1077bd79bce8SPatrick Williams                             logServiceArrayLocal.emplace_back(
1078bd79bce8SPatrick Williams                                 std::move(member));
1079613dabeaSEd Tanous 
108045ca1b86SEd Tanous                             asyncResp->res.jsonValue["Members@odata.count"] =
108123a21a1cSEd Tanous                                 logServiceArrayLocal.size();
1082a3316fc6SZhikuiRen                             return;
1083a3316fc6SZhikuiRen                         }
1084a3316fc6SZhikuiRen                     }
10857a1dbc48SGeorge Liu                 });
10867e860f15SJohn Edward Broadbent         });
1087c4bf6374SJason M. Bills }
1088c4bf6374SJason M. Bills 
10897e860f15SJohn Edward Broadbent inline void requestRoutesEventLogService(App& app)
1090c4bf6374SJason M. Bills {
109122d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/EventLog/")
1092ed398213SEd Tanous         .privileges(redfish::privileges::getLogService)
1093bd79bce8SPatrick Williams         .methods(
1094bd79bce8SPatrick Williams             boost::beast::http::verb::
1095bd79bce8SPatrick Williams                 get)([&app](const crow::Request& req,
109622d268cbSEd Tanous                             const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
109722d268cbSEd Tanous                             const std::string& systemName) {
10983ba00073SCarson Labrado             if (!redfish::setUpRedfishRoute(app, req, asyncResp))
109945ca1b86SEd Tanous             {
110045ca1b86SEd Tanous                 return;
110145ca1b86SEd Tanous             }
1102253f11b8SEd Tanous             if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
110322d268cbSEd Tanous             {
110422d268cbSEd Tanous                 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
110522d268cbSEd Tanous                                            systemName);
110622d268cbSEd Tanous                 return;
110722d268cbSEd Tanous             }
1108c4bf6374SJason M. Bills             asyncResp->res.jsonValue["@odata.id"] =
1109253f11b8SEd Tanous                 std::format("/redfish/v1/Systems/{}/LogServices/EventLog",
1110253f11b8SEd Tanous                             BMCWEB_REDFISH_SYSTEM_URI_NAME);
1111c4bf6374SJason M. Bills             asyncResp->res.jsonValue["@odata.type"] =
1112b25644a1SJanet Adkins                 "#LogService.v1_2_0.LogService";
1113c4bf6374SJason M. Bills             asyncResp->res.jsonValue["Name"] = "Event Log Service";
1114bd79bce8SPatrick Williams             asyncResp->res.jsonValue["Description"] =
1115bd79bce8SPatrick Williams                 "System Event Log Service";
1116c4bf6374SJason M. Bills             asyncResp->res.jsonValue["Id"] = "EventLog";
1117539d8c6bSEd Tanous             asyncResp->res.jsonValue["OverWritePolicy"] =
1118539d8c6bSEd Tanous                 log_service::OverWritePolicy::WrapsWhenFull;
11197c8c4058STejas Patil 
11207c8c4058STejas Patil             std::pair<std::string, std::string> redfishDateTimeOffset =
11212b82937eSEd Tanous                 redfish::time_utils::getDateTimeOffsetNow();
11227c8c4058STejas Patil 
11237c8c4058STejas Patil             asyncResp->res.jsonValue["DateTime"] = redfishDateTimeOffset.first;
11247c8c4058STejas Patil             asyncResp->res.jsonValue["DateTimeLocalOffset"] =
11257c8c4058STejas Patil                 redfishDateTimeOffset.second;
11267c8c4058STejas Patil 
1127bd79bce8SPatrick Williams             asyncResp->res.jsonValue["Entries"]["@odata.id"] = std::format(
1128bd79bce8SPatrick Williams                 "/redfish/v1/Systems/{}/LogServices/EventLog/Entries",
1129253f11b8SEd Tanous                 BMCWEB_REDFISH_SYSTEM_URI_NAME);
1130bd79bce8SPatrick Williams             asyncResp->res
1131bd79bce8SPatrick Williams                 .jsonValue["Actions"]["#LogService.ClearLog"]["target"]
1132e7d6c8b2SGunnar Mills 
113320fa6a2cSEd Tanous                 = std::format(
1134253f11b8SEd Tanous                     "/redfish/v1/Systems/{}/LogServices/EventLog/Actions/LogService.ClearLog",
113520fa6a2cSEd Tanous                     BMCWEB_REDFISH_SYSTEM_URI_NAME);
1136*08fad5d9SCorey Ethington 
1137*08fad5d9SCorey Ethington             etag_utils::setEtagOmitDateTimeHandler(asyncResp);
11387e860f15SJohn Edward Broadbent         });
1139489640c6SJason M. Bills }
1140489640c6SJason M. Bills 
11417f3726a2SMyung Bae inline void fillEventLogLogEntryFromDbusLogEntry(
11427f3726a2SMyung Bae     const DbusEventLogEntry& entry, nlohmann::json& objectToFillOut)
1143898f2aa2SEd Tanous {
1144898f2aa2SEd Tanous     objectToFillOut["@odata.type"] = "#LogEntry.v1_9_0.LogEntry";
1145898f2aa2SEd Tanous     objectToFillOut["@odata.id"] = boost::urls::format(
1146898f2aa2SEd Tanous         "/redfish/v1/Systems/{}/LogServices/EventLog/Entries/{}",
1147262dcc1cSAlexander Hansen         BMCWEB_REDFISH_SYSTEM_URI_NAME, std::to_string(entry.Id));
1148898f2aa2SEd Tanous     objectToFillOut["Name"] = "System Event Log Entry";
1149262dcc1cSAlexander Hansen     objectToFillOut["Id"] = std::to_string(entry.Id);
1150262dcc1cSAlexander Hansen     objectToFillOut["Message"] = entry.Message;
1151262dcc1cSAlexander Hansen     objectToFillOut["Resolved"] = entry.Resolved;
1152262dcc1cSAlexander Hansen     std::optional<bool> notifyAction =
1153262dcc1cSAlexander Hansen         getProviderNotifyAction(entry.ServiceProviderNotify);
1154898f2aa2SEd Tanous     if (notifyAction)
1155898f2aa2SEd Tanous     {
1156898f2aa2SEd Tanous         objectToFillOut["ServiceProviderNotified"] = *notifyAction;
1157898f2aa2SEd Tanous     }
1158262dcc1cSAlexander Hansen     if ((entry.Resolution != nullptr) && !entry.Resolution->empty())
1159898f2aa2SEd Tanous     {
1160262dcc1cSAlexander Hansen         objectToFillOut["Resolution"] = *entry.Resolution;
1161898f2aa2SEd Tanous     }
1162898f2aa2SEd Tanous     objectToFillOut["EntryType"] = "Event";
1163262dcc1cSAlexander Hansen     objectToFillOut["Severity"] =
1164262dcc1cSAlexander Hansen         translateSeverityDbusToRedfish(entry.Severity);
1165898f2aa2SEd Tanous     objectToFillOut["Created"] =
1166262dcc1cSAlexander Hansen         redfish::time_utils::getDateTimeUintMs(entry.Timestamp);
1167898f2aa2SEd Tanous     objectToFillOut["Modified"] =
1168262dcc1cSAlexander Hansen         redfish::time_utils::getDateTimeUintMs(entry.UpdateTimestamp);
1169262dcc1cSAlexander Hansen     if (entry.Path != nullptr)
1170898f2aa2SEd Tanous     {
1171898f2aa2SEd Tanous         objectToFillOut["AdditionalDataURI"] = boost::urls::format(
1172898f2aa2SEd Tanous             "/redfish/v1/Systems/{}/LogServices/EventLog/Entries/{}/attachment",
1173262dcc1cSAlexander Hansen             BMCWEB_REDFISH_SYSTEM_URI_NAME, std::to_string(entry.Id));
1174898f2aa2SEd Tanous     }
1175898f2aa2SEd Tanous }
1176898f2aa2SEd Tanous 
1177b729096dSEd Tanous inline void afterLogEntriesGetManagedObjects(
1178b729096dSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1179b729096dSEd Tanous     const boost::system::error_code& ec,
1180b729096dSEd Tanous     const dbus::utility::ManagedObjectType& resp)
1181b729096dSEd Tanous {
1182b729096dSEd Tanous     if (ec)
1183b729096dSEd Tanous     {
1184b729096dSEd Tanous         // TODO Handle for specific error code
1185b729096dSEd Tanous         BMCWEB_LOG_ERROR("getLogEntriesIfaceData resp_handler got error {}",
1186b729096dSEd Tanous                          ec);
1187b729096dSEd Tanous         messages::internalError(asyncResp->res);
1188b729096dSEd Tanous         return;
1189b729096dSEd Tanous     }
1190b729096dSEd Tanous     nlohmann::json::array_t entriesArray;
1191b729096dSEd Tanous     for (const auto& objectPath : resp)
1192b729096dSEd Tanous     {
1193898f2aa2SEd Tanous         dbus::utility::DBusPropertiesMap propsFlattened;
1194bd79bce8SPatrick Williams         auto isEntry =
1195bd79bce8SPatrick Williams             std::ranges::find_if(objectPath.second, [](const auto& object) {
1196898f2aa2SEd Tanous                 return object.first == "xyz.openbmc_project.Logging.Entry";
1197898f2aa2SEd Tanous             });
1198898f2aa2SEd Tanous         if (isEntry == objectPath.second.end())
1199b729096dSEd Tanous         {
1200b729096dSEd Tanous             continue;
1201b729096dSEd Tanous         }
12027f3726a2SMyung Bae 
1203898f2aa2SEd Tanous         for (const auto& interfaceMap : objectPath.second)
1204b729096dSEd Tanous         {
1205898f2aa2SEd Tanous             for (const auto& propertyMap : interfaceMap.second)
1206b729096dSEd Tanous             {
1207898f2aa2SEd Tanous                 propsFlattened.emplace_back(propertyMap.first,
1208898f2aa2SEd Tanous                                             propertyMap.second);
1209b729096dSEd Tanous             }
1210b729096dSEd Tanous         }
12117f3726a2SMyung Bae         std::optional<DbusEventLogEntry> optEntry =
12127f3726a2SMyung Bae             fillDbusEventLogEntryFromPropertyMap(propsFlattened);
12137f3726a2SMyung Bae 
12147f3726a2SMyung Bae         if (!optEntry.has_value())
121590896601SIgor Kanyuka         {
12167f3726a2SMyung Bae             messages::internalError(asyncResp->res);
121790896601SIgor Kanyuka             return;
121890896601SIgor Kanyuka         }
12197f3726a2SMyung Bae         fillEventLogLogEntryFromDbusLogEntry(*optEntry,
12207f3726a2SMyung Bae                                              entriesArray.emplace_back());
1221b729096dSEd Tanous     }
1222898f2aa2SEd Tanous 
122390896601SIgor Kanyuka     redfish::json_util::sortJsonArrayByKey(entriesArray, "Id");
1224b729096dSEd Tanous     asyncResp->res.jsonValue["Members@odata.count"] = entriesArray.size();
1225b729096dSEd Tanous     asyncResp->res.jsonValue["Members"] = std::move(entriesArray);
1226b729096dSEd Tanous }
1227b729096dSEd Tanous 
1228599b9af3SAlexander Hansen inline void dBusEventLogEntryCollection(
1229599b9af3SAlexander Hansen     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1230599b9af3SAlexander Hansen {
1231599b9af3SAlexander Hansen     // Collections don't include the static data added by SubRoute
1232599b9af3SAlexander Hansen     // because it has a duplicate entry for members
1233599b9af3SAlexander Hansen     asyncResp->res.jsonValue["@odata.type"] =
1234599b9af3SAlexander Hansen         "#LogEntryCollection.LogEntryCollection";
1235599b9af3SAlexander Hansen     asyncResp->res.jsonValue["@odata.id"] =
1236599b9af3SAlexander Hansen         std::format("/redfish/v1/Systems/{}/LogServices/EventLog/Entries",
1237599b9af3SAlexander Hansen                     BMCWEB_REDFISH_SYSTEM_URI_NAME);
1238599b9af3SAlexander Hansen     asyncResp->res.jsonValue["Name"] = "System Event Log Entries";
1239599b9af3SAlexander Hansen     asyncResp->res.jsonValue["Description"] =
1240599b9af3SAlexander Hansen         "Collection of System Event Log Entries";
1241599b9af3SAlexander Hansen 
1242599b9af3SAlexander Hansen     // DBus implementation of EventLog/Entries
1243599b9af3SAlexander Hansen     // Make call to Logging Service to find all log entry objects
1244599b9af3SAlexander Hansen     sdbusplus::message::object_path path("/xyz/openbmc_project/logging");
1245599b9af3SAlexander Hansen     dbus::utility::getManagedObjects(
1246599b9af3SAlexander Hansen         "xyz.openbmc_project.Logging", path,
1247599b9af3SAlexander Hansen         [asyncResp](const boost::system::error_code& ec,
1248599b9af3SAlexander Hansen                     const dbus::utility::ManagedObjectType& resp) {
1249b729096dSEd Tanous             afterLogEntriesGetManagedObjects(asyncResp, ec, resp);
12507e860f15SJohn Edward Broadbent         });
125108a4e4b5SAnthony Wilson }
125208a4e4b5SAnthony Wilson 
12537e860f15SJohn Edward Broadbent inline void requestRoutesDBusEventLogEntryCollection(App& app)
125408a4e4b5SAnthony Wilson {
125522d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/")
1256ed398213SEd Tanous         .privileges(redfish::privileges::getLogEntryCollection)
1257002d39b4SEd Tanous         .methods(boost::beast::http::verb::get)(
1258002d39b4SEd Tanous             [&app](const crow::Request& req,
125922d268cbSEd Tanous                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
126022d268cbSEd Tanous                    const std::string& systemName) {
12613ba00073SCarson Labrado                 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
126245ca1b86SEd Tanous                 {
126345ca1b86SEd Tanous                     return;
126445ca1b86SEd Tanous                 }
126525b54dbaSEd Tanous                 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
12667f3e84a1SEd Tanous                 {
12677f3e84a1SEd Tanous                     // Option currently returns no systems.  TBD
12687f3e84a1SEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
12697f3e84a1SEd Tanous                                                systemName);
12707f3e84a1SEd Tanous                     return;
12717f3e84a1SEd Tanous                 }
1272253f11b8SEd Tanous                 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
127322d268cbSEd Tanous                 {
127422d268cbSEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
127522d268cbSEd Tanous                                                systemName);
127622d268cbSEd Tanous                     return;
127722d268cbSEd Tanous                 }
1278599b9af3SAlexander Hansen                 dBusEventLogEntryCollection(asyncResp);
1279599b9af3SAlexander Hansen             });
1280599b9af3SAlexander Hansen }
128122d268cbSEd Tanous 
1282c6b7cae2SMyung Bae inline void afterDBusEventLogEntryGet(
1283c6b7cae2SMyung Bae     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1284c6b7cae2SMyung Bae     const std::string& entryID, const boost::system::error_code& ec,
1285c6b7cae2SMyung Bae     const dbus::utility::DBusPropertiesMap& resp)
1286c6b7cae2SMyung Bae {
1287c6b7cae2SMyung Bae     if (ec.value() == EBADR)
1288c6b7cae2SMyung Bae     {
1289c6b7cae2SMyung Bae         messages::resourceNotFound(asyncResp->res, "EventLogEntry", entryID);
1290c6b7cae2SMyung Bae         return;
1291c6b7cae2SMyung Bae     }
1292c6b7cae2SMyung Bae     if (ec)
1293c6b7cae2SMyung Bae     {
1294c6b7cae2SMyung Bae         BMCWEB_LOG_ERROR("EventLogEntry (DBus) resp_handler got error {}", ec);
1295c6b7cae2SMyung Bae         messages::internalError(asyncResp->res);
1296c6b7cae2SMyung Bae         return;
1297c6b7cae2SMyung Bae     }
1298c6b7cae2SMyung Bae 
12997f3726a2SMyung Bae     std::optional<DbusEventLogEntry> optEntry =
13007f3726a2SMyung Bae         fillDbusEventLogEntryFromPropertyMap(resp);
13017f3726a2SMyung Bae 
13027f3726a2SMyung Bae     if (!optEntry.has_value())
13037f3726a2SMyung Bae     {
13047f3726a2SMyung Bae         messages::internalError(asyncResp->res);
13057f3726a2SMyung Bae         return;
13067f3726a2SMyung Bae     }
13077f3726a2SMyung Bae 
13087f3726a2SMyung Bae     fillEventLogLogEntryFromDbusLogEntry(*optEntry, asyncResp->res.jsonValue);
1309c6b7cae2SMyung Bae }
1310c6b7cae2SMyung Bae 
1311bd79bce8SPatrick Williams inline void dBusEventLogEntryGet(
1312bd79bce8SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, std::string entryID)
1313599b9af3SAlexander Hansen {
1314599b9af3SAlexander Hansen     dbus::utility::escapePathForDbus(entryID);
131508a4e4b5SAnthony Wilson 
1316cb92c03bSAndrew Geissler     // DBus implementation of EventLog/Entries
1317cb92c03bSAndrew Geissler     // Make call to Logging Service to find all log entry objects
1318deae6a78SEd Tanous     dbus::utility::getAllProperties(
1319deae6a78SEd Tanous         "xyz.openbmc_project.Logging",
1320599b9af3SAlexander Hansen         "/xyz/openbmc_project/logging/entry/" + entryID, "",
1321c6b7cae2SMyung Bae         std::bind_front(afterDBusEventLogEntryGet, asyncResp, entryID));
13227e860f15SJohn Edward Broadbent }
1323599b9af3SAlexander Hansen 
1324504af5a0SPatrick Williams inline void dBusEventLogEntryPatch(
1325504af5a0SPatrick Williams     const crow::Request& req,
1326599b9af3SAlexander Hansen     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1327599b9af3SAlexander Hansen     const std::string& entryId)
1328599b9af3SAlexander Hansen {
1329599b9af3SAlexander Hansen     std::optional<bool> resolved;
1330599b9af3SAlexander Hansen 
1331599b9af3SAlexander Hansen     if (!json_util::readJsonPatch(req, asyncResp->res, "Resolved", resolved))
1332599b9af3SAlexander Hansen     {
1333599b9af3SAlexander Hansen         return;
1334599b9af3SAlexander Hansen     }
1335599b9af3SAlexander Hansen     BMCWEB_LOG_DEBUG("Set Resolved");
1336599b9af3SAlexander Hansen 
1337599b9af3SAlexander Hansen     setDbusProperty(asyncResp, "Resolved", "xyz.openbmc_project.Logging",
1338599b9af3SAlexander Hansen                     "/xyz/openbmc_project/logging/entry/" + entryId,
1339599b9af3SAlexander Hansen                     "xyz.openbmc_project.Logging.Entry", "Resolved",
1340599b9af3SAlexander Hansen                     resolved.value_or(false));
1341599b9af3SAlexander Hansen }
1342599b9af3SAlexander Hansen 
1343bd79bce8SPatrick Williams inline void dBusEventLogEntryDelete(
1344bd79bce8SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, std::string entryID)
1345599b9af3SAlexander Hansen {
1346599b9af3SAlexander Hansen     BMCWEB_LOG_DEBUG("Do delete single event entries.");
1347599b9af3SAlexander Hansen 
1348599b9af3SAlexander Hansen     dbus::utility::escapePathForDbus(entryID);
1349599b9af3SAlexander Hansen 
1350599b9af3SAlexander Hansen     // Process response from Logging service.
1351599b9af3SAlexander Hansen     auto respHandler = [asyncResp,
1352599b9af3SAlexander Hansen                         entryID](const boost::system::error_code& ec) {
1353599b9af3SAlexander Hansen         BMCWEB_LOG_DEBUG("EventLogEntry (DBus) doDelete callback: Done");
1354599b9af3SAlexander Hansen         if (ec)
1355599b9af3SAlexander Hansen         {
1356599b9af3SAlexander Hansen             if (ec.value() == EBADR)
1357599b9af3SAlexander Hansen             {
1358599b9af3SAlexander Hansen                 messages::resourceNotFound(asyncResp->res, "LogEntry", entryID);
1359599b9af3SAlexander Hansen                 return;
1360599b9af3SAlexander Hansen             }
1361599b9af3SAlexander Hansen             // TODO Handle for specific error code
1362599b9af3SAlexander Hansen             BMCWEB_LOG_ERROR(
1363599b9af3SAlexander Hansen                 "EventLogEntry (DBus) doDelete respHandler got error {}", ec);
1364599b9af3SAlexander Hansen             asyncResp->res.result(
1365599b9af3SAlexander Hansen                 boost::beast::http::status::internal_server_error);
1366599b9af3SAlexander Hansen             return;
1367599b9af3SAlexander Hansen         }
1368599b9af3SAlexander Hansen 
1369599b9af3SAlexander Hansen         asyncResp->res.result(boost::beast::http::status::ok);
1370599b9af3SAlexander Hansen     };
1371599b9af3SAlexander Hansen 
1372599b9af3SAlexander Hansen     // Make call to Logging service to request Delete Log
1373177612aaSEd Tanous     dbus::utility::async_method_call(
1374177612aaSEd Tanous         asyncResp, respHandler, "xyz.openbmc_project.Logging",
1375599b9af3SAlexander Hansen         "/xyz/openbmc_project/logging/entry/" + entryID,
1376599b9af3SAlexander Hansen         "xyz.openbmc_project.Object.Delete", "Delete");
13777e860f15SJohn Edward Broadbent }
13787e860f15SJohn Edward Broadbent 
13797e860f15SJohn Edward Broadbent inline void requestRoutesDBusEventLogEntry(App& app)
13807e860f15SJohn Edward Broadbent {
13817e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(
138222d268cbSEd Tanous         app, "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/<str>/")
1383ed398213SEd Tanous         .privileges(redfish::privileges::getLogEntry)
1384002d39b4SEd Tanous         .methods(boost::beast::http::verb::get)(
1385002d39b4SEd Tanous             [&app](const crow::Request& req,
13867e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1387898f2aa2SEd Tanous                    const std::string& systemName, const std::string& entryId) {
13883ba00073SCarson Labrado                 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
13897e860f15SJohn Edward Broadbent                 {
139045ca1b86SEd Tanous                     return;
139145ca1b86SEd Tanous                 }
139225b54dbaSEd Tanous                 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
13937f3e84a1SEd Tanous                 {
13947f3e84a1SEd Tanous                     // Option currently returns no systems.  TBD
13957f3e84a1SEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
13967f3e84a1SEd Tanous                                                systemName);
13977f3e84a1SEd Tanous                     return;
13987f3e84a1SEd Tanous                 }
1399253f11b8SEd Tanous                 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
140022d268cbSEd Tanous                 {
140122d268cbSEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
140222d268cbSEd Tanous                                                systemName);
140322d268cbSEd Tanous                     return;
140422d268cbSEd Tanous                 }
140522d268cbSEd Tanous 
1406898f2aa2SEd Tanous                 dBusEventLogEntryGet(asyncResp, entryId);
14077e860f15SJohn Edward Broadbent             });
1408336e96c6SChicago Duan 
14097e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(
141022d268cbSEd Tanous         app, "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/<str>/")
1411ed398213SEd Tanous         .privileges(redfish::privileges::patchLogEntry)
14127e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::patch)(
141345ca1b86SEd Tanous             [&app](const crow::Request& req,
14147e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
141522d268cbSEd Tanous                    const std::string& systemName, const std::string& entryId) {
14163ba00073SCarson Labrado                 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
141745ca1b86SEd Tanous                 {
141845ca1b86SEd Tanous                     return;
141945ca1b86SEd Tanous                 }
142025b54dbaSEd Tanous                 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
14217f3e84a1SEd Tanous                 {
14227f3e84a1SEd Tanous                     // Option currently returns no systems.  TBD
14237f3e84a1SEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
14247f3e84a1SEd Tanous                                                systemName);
14257f3e84a1SEd Tanous                     return;
14267f3e84a1SEd Tanous                 }
1427253f11b8SEd Tanous                 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
142822d268cbSEd Tanous                 {
142922d268cbSEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
143022d268cbSEd Tanous                                                systemName);
143122d268cbSEd Tanous                     return;
143222d268cbSEd Tanous                 }
143375710de2SXiaochao Ma 
1434599b9af3SAlexander Hansen                 dBusEventLogEntryPatch(req, asyncResp, entryId);
14357e860f15SJohn Edward Broadbent             });
143675710de2SXiaochao Ma 
14377e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(
143822d268cbSEd Tanous         app, "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/<str>/")
1439fff6a4d3SAbhishek Patel         .privileges(
1440fff6a4d3SAbhishek Patel             redfish::privileges::
1441fff6a4d3SAbhishek Patel                 deleteLogEntrySubOverComputerSystemLogServiceCollectionLogServiceLogEntryCollection)
1442002d39b4SEd Tanous         .methods(boost::beast::http::verb::delete_)(
1443002d39b4SEd Tanous             [&app](const crow::Request& req,
1444002d39b4SEd Tanous                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
144522d268cbSEd Tanous                    const std::string& systemName, const std::string& param) {
14463ba00073SCarson Labrado                 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1447336e96c6SChicago Duan                 {
144845ca1b86SEd Tanous                     return;
144945ca1b86SEd Tanous                 }
145025b54dbaSEd Tanous                 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
14517f3e84a1SEd Tanous                 {
14527f3e84a1SEd Tanous                     // Option currently returns no systems.  TBD
14537f3e84a1SEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
14547f3e84a1SEd Tanous                                                systemName);
14557f3e84a1SEd Tanous                     return;
14567f3e84a1SEd Tanous                 }
1457253f11b8SEd Tanous                 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
145822d268cbSEd Tanous                 {
145922d268cbSEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
146022d268cbSEd Tanous                                                systemName);
146122d268cbSEd Tanous                     return;
146222d268cbSEd Tanous                 }
1463599b9af3SAlexander Hansen                 dBusEventLogEntryDelete(asyncResp, param);
14647e860f15SJohn Edward Broadbent             });
1465400fd1fbSAdriana Kobylak }
1466400fd1fbSAdriana Kobylak 
1467dd72e87bSClaire Weinan inline void handleBMCLogServicesCollectionGet(
1468fdd26906SClaire Weinan     crow::App& app, const crow::Request& req,
1469253f11b8SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1470253f11b8SEd Tanous     const std::string& managerId)
14711da66f75SEd Tanous {
14723ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
147345ca1b86SEd Tanous     {
147445ca1b86SEd Tanous         return;
147545ca1b86SEd Tanous     }
1476253f11b8SEd Tanous 
1477253f11b8SEd Tanous     if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1478253f11b8SEd Tanous     {
1479253f11b8SEd Tanous         messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1480253f11b8SEd Tanous         return;
1481253f11b8SEd Tanous     }
1482253f11b8SEd Tanous 
14837e860f15SJohn Edward Broadbent     // Collections don't include the static data added by SubRoute
14847e860f15SJohn Edward Broadbent     // because it has a duplicate entry for members
1485e1f26343SJason M. Bills     asyncResp->res.jsonValue["@odata.type"] =
14861da66f75SEd Tanous         "#LogServiceCollection.LogServiceCollection";
1487253f11b8SEd Tanous     asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
1488253f11b8SEd Tanous         "/redfish/v1/Managers/{}/LogServices", BMCWEB_REDFISH_MANAGER_URI_NAME);
1489002d39b4SEd Tanous     asyncResp->res.jsonValue["Name"] = "Open BMC Log Services Collection";
1490e1f26343SJason M. Bills     asyncResp->res.jsonValue["Description"] =
14911da66f75SEd Tanous         "Collection of LogServices for this Manager";
1492002d39b4SEd Tanous     nlohmann::json& logServiceArray = asyncResp->res.jsonValue["Members"];
1493c4bf6374SJason M. Bills     logServiceArray = nlohmann::json::array();
1494fdd26906SClaire Weinan 
149525b54dbaSEd Tanous     if constexpr (BMCWEB_REDFISH_BMC_JOURNAL)
149625b54dbaSEd Tanous     {
1497613dabeaSEd Tanous         nlohmann::json::object_t journal;
1498253f11b8SEd Tanous         journal["@odata.id"] =
1499253f11b8SEd Tanous             boost::urls::format("/redfish/v1/Managers/{}/LogServices/Journal",
1500253f11b8SEd Tanous                                 BMCWEB_REDFISH_MANAGER_URI_NAME);
1501b2ba3072SPatrick Williams         logServiceArray.emplace_back(std::move(journal));
150225b54dbaSEd Tanous     }
1503fdd26906SClaire Weinan 
1504fdd26906SClaire Weinan     asyncResp->res.jsonValue["Members@odata.count"] = logServiceArray.size();
1505fdd26906SClaire Weinan 
150625b54dbaSEd Tanous     if constexpr (BMCWEB_REDFISH_DUMP_LOG)
150725b54dbaSEd Tanous     {
150815912159SGeorge Liu         constexpr std::array<std::string_view, 1> interfaces = {
15097a1dbc48SGeorge Liu             "xyz.openbmc_project.Collection.DeleteAll"};
15107a1dbc48SGeorge Liu         dbus::utility::getSubTreePaths(
15117a1dbc48SGeorge Liu             "/xyz/openbmc_project/dump", 0, interfaces,
151225b54dbaSEd Tanous             [asyncResp](const boost::system::error_code& ec,
151325b54dbaSEd Tanous                         const dbus::utility::MapperGetSubTreePathsResponse&
151425b54dbaSEd Tanous                             subTreePaths) {
1515fdd26906SClaire Weinan                 if (ec)
1516fdd26906SClaire Weinan                 {
151762598e31SEd Tanous                     BMCWEB_LOG_ERROR(
151862598e31SEd Tanous                         "handleBMCLogServicesCollectionGet respHandler got error {}",
151962598e31SEd Tanous                         ec);
1520bd79bce8SPatrick Williams                     // Assume that getting an error simply means there are no
1521bd79bce8SPatrick Williams                     // dump LogServices. Return without adding any error
1522bd79bce8SPatrick Williams                     // response.
1523fdd26906SClaire Weinan                     return;
1524fdd26906SClaire Weinan                 }
1525fdd26906SClaire Weinan 
1526fdd26906SClaire Weinan                 nlohmann::json& logServiceArrayLocal =
1527fdd26906SClaire Weinan                     asyncResp->res.jsonValue["Members"];
1528fdd26906SClaire Weinan 
1529fdd26906SClaire Weinan                 for (const std::string& path : subTreePaths)
1530fdd26906SClaire Weinan                 {
1531fdd26906SClaire Weinan                     if (path == "/xyz/openbmc_project/dump/bmc")
1532fdd26906SClaire Weinan                     {
1533613dabeaSEd Tanous                         nlohmann::json::object_t member;
1534253f11b8SEd Tanous                         member["@odata.id"] = boost::urls::format(
1535253f11b8SEd Tanous                             "/redfish/v1/Managers/{}/LogServices/Dump",
1536253f11b8SEd Tanous                             BMCWEB_REDFISH_MANAGER_URI_NAME);
1537b2ba3072SPatrick Williams                         logServiceArrayLocal.emplace_back(std::move(member));
1538fdd26906SClaire Weinan                     }
1539fdd26906SClaire Weinan                     else if (path == "/xyz/openbmc_project/dump/faultlog")
1540fdd26906SClaire Weinan                     {
1541613dabeaSEd Tanous                         nlohmann::json::object_t member;
1542253f11b8SEd Tanous                         member["@odata.id"] = boost::urls::format(
1543253f11b8SEd Tanous                             "/redfish/v1/Managers/{}/LogServices/FaultLog",
1544253f11b8SEd Tanous                             BMCWEB_REDFISH_MANAGER_URI_NAME);
1545b2ba3072SPatrick Williams                         logServiceArrayLocal.emplace_back(std::move(member));
1546fdd26906SClaire Weinan                     }
1547fdd26906SClaire Weinan                 }
1548fdd26906SClaire Weinan 
1549e1f26343SJason M. Bills                 asyncResp->res.jsonValue["Members@odata.count"] =
1550fdd26906SClaire Weinan                     logServiceArrayLocal.size();
15517a1dbc48SGeorge Liu             });
155225b54dbaSEd Tanous     }
1553fdd26906SClaire Weinan }
1554fdd26906SClaire Weinan 
1555fdd26906SClaire Weinan inline void requestRoutesBMCLogServiceCollection(App& app)
1556fdd26906SClaire Weinan {
1557253f11b8SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/LogServices/")
1558fdd26906SClaire Weinan         .privileges(redfish::privileges::getLogServiceCollection)
1559fdd26906SClaire Weinan         .methods(boost::beast::http::verb::get)(
1560dd72e87bSClaire Weinan             std::bind_front(handleBMCLogServicesCollectionGet, std::ref(app)));
1561e1f26343SJason M. Bills }
1562e1f26343SJason M. Bills 
1563504af5a0SPatrick Williams inline void getDumpServiceInfo(
1564504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1565fdd26906SClaire Weinan     const std::string& dumpType)
1566c9bb6861Sraviteja-b {
1567fdd26906SClaire Weinan     std::string dumpPath;
1568539d8c6bSEd Tanous     log_service::OverWritePolicy overWritePolicy =
1569539d8c6bSEd Tanous         log_service::OverWritePolicy::Invalid;
1570fdd26906SClaire Weinan     bool collectDiagnosticDataSupported = false;
1571fdd26906SClaire Weinan 
1572fdd26906SClaire Weinan     if (dumpType == "BMC")
157345ca1b86SEd Tanous     {
1574253f11b8SEd Tanous         dumpPath = std::format("/redfish/v1/Managers/{}/LogServices/Dump",
1575253f11b8SEd Tanous                                BMCWEB_REDFISH_MANAGER_URI_NAME);
1576539d8c6bSEd Tanous         overWritePolicy = log_service::OverWritePolicy::WrapsWhenFull;
1577fdd26906SClaire Weinan         collectDiagnosticDataSupported = true;
1578fdd26906SClaire Weinan     }
1579fdd26906SClaire Weinan     else if (dumpType == "FaultLog")
1580fdd26906SClaire Weinan     {
1581253f11b8SEd Tanous         dumpPath = std::format("/redfish/v1/Managers/{}/LogServices/FaultLog",
1582253f11b8SEd Tanous                                BMCWEB_REDFISH_MANAGER_URI_NAME);
1583539d8c6bSEd Tanous         overWritePolicy = log_service::OverWritePolicy::Unknown;
1584fdd26906SClaire Weinan         collectDiagnosticDataSupported = false;
1585fdd26906SClaire Weinan     }
1586fdd26906SClaire Weinan     else if (dumpType == "System")
1587fdd26906SClaire Weinan     {
1588253f11b8SEd Tanous         dumpPath = std::format("/redfish/v1/Systems/{}/LogServices/Dump",
1589253f11b8SEd Tanous                                BMCWEB_REDFISH_SYSTEM_URI_NAME);
1590539d8c6bSEd Tanous         overWritePolicy = log_service::OverWritePolicy::WrapsWhenFull;
1591fdd26906SClaire Weinan         collectDiagnosticDataSupported = true;
1592fdd26906SClaire Weinan     }
1593fdd26906SClaire Weinan     else
1594fdd26906SClaire Weinan     {
159562598e31SEd Tanous         BMCWEB_LOG_ERROR("getDumpServiceInfo() invalid dump type: {}",
159662598e31SEd Tanous                          dumpType);
1597fdd26906SClaire Weinan         messages::internalError(asyncResp->res);
159845ca1b86SEd Tanous         return;
159945ca1b86SEd Tanous     }
1600fdd26906SClaire Weinan 
1601fdd26906SClaire Weinan     asyncResp->res.jsonValue["@odata.id"] = dumpPath;
1602fdd26906SClaire Weinan     asyncResp->res.jsonValue["@odata.type"] = "#LogService.v1_2_0.LogService";
1603c9bb6861Sraviteja-b     asyncResp->res.jsonValue["Name"] = "Dump LogService";
1604fdd26906SClaire Weinan     asyncResp->res.jsonValue["Description"] = dumpType + " Dump LogService";
1605fdd26906SClaire Weinan     asyncResp->res.jsonValue["Id"] = std::filesystem::path(dumpPath).filename();
1606539d8c6bSEd Tanous     asyncResp->res.jsonValue["OverWritePolicy"] = overWritePolicy;
16077c8c4058STejas Patil 
16087c8c4058STejas Patil     std::pair<std::string, std::string> redfishDateTimeOffset =
16092b82937eSEd Tanous         redfish::time_utils::getDateTimeOffsetNow();
16100fda0f12SGeorge Liu     asyncResp->res.jsonValue["DateTime"] = redfishDateTimeOffset.first;
16117c8c4058STejas Patil     asyncResp->res.jsonValue["DateTimeLocalOffset"] =
16127c8c4058STejas Patil         redfishDateTimeOffset.second;
16137c8c4058STejas Patil 
1614fdd26906SClaire Weinan     asyncResp->res.jsonValue["Entries"]["@odata.id"] = dumpPath + "/Entries";
1615fdd26906SClaire Weinan 
1616fdd26906SClaire Weinan     if (collectDiagnosticDataSupported)
1617fdd26906SClaire Weinan     {
1618002d39b4SEd Tanous         asyncResp->res.jsonValue["Actions"]["#LogService.CollectDiagnosticData"]
16191476687dSEd Tanous                                 ["target"] =
1620fdd26906SClaire Weinan             dumpPath + "/Actions/LogService.CollectDiagnosticData";
1621fdd26906SClaire Weinan     }
16220d946211SClaire Weinan 
1623*08fad5d9SCorey Ethington     etag_utils::setEtagOmitDateTimeHandler(asyncResp);
1624*08fad5d9SCorey Ethington 
16250d946211SClaire Weinan     constexpr std::array<std::string_view, 1> interfaces = {deleteAllInterface};
16260d946211SClaire Weinan     dbus::utility::getSubTreePaths(
16270d946211SClaire Weinan         "/xyz/openbmc_project/dump", 0, interfaces,
16280d946211SClaire Weinan         [asyncResp, dumpType, dumpPath](
16290d946211SClaire Weinan             const boost::system::error_code& ec,
16300d946211SClaire Weinan             const dbus::utility::MapperGetSubTreePathsResponse& subTreePaths) {
16310d946211SClaire Weinan             if (ec)
16320d946211SClaire Weinan             {
1633bd79bce8SPatrick Williams                 BMCWEB_LOG_ERROR("getDumpServiceInfo respHandler got error {}",
1634bd79bce8SPatrick Williams                                  ec);
16350d946211SClaire Weinan                 // Assume that getting an error simply means there are no dump
16360d946211SClaire Weinan                 // LogServices. Return without adding any error response.
16370d946211SClaire Weinan                 return;
16380d946211SClaire Weinan             }
163918f8f608SEd Tanous             std::string dbusDumpPath = getDumpPath(dumpType);
16400d946211SClaire Weinan             for (const std::string& path : subTreePaths)
16410d946211SClaire Weinan             {
16420d946211SClaire Weinan                 if (path == dbusDumpPath)
16430d946211SClaire Weinan                 {
1644bd79bce8SPatrick Williams                     asyncResp->res.jsonValue["Actions"]["#LogService.ClearLog"]
1645bd79bce8SPatrick Williams                                             ["target"] =
16460d946211SClaire Weinan                         dumpPath + "/Actions/LogService.ClearLog";
16470d946211SClaire Weinan                     break;
16480d946211SClaire Weinan                 }
16490d946211SClaire Weinan             }
16500d946211SClaire Weinan         });
1651c9bb6861Sraviteja-b }
1652c9bb6861Sraviteja-b 
1653fdd26906SClaire Weinan inline void handleLogServicesDumpServiceGet(
1654fdd26906SClaire Weinan     crow::App& app, const std::string& dumpType, const crow::Request& req,
1655253f11b8SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1656253f11b8SEd Tanous     const std::string& managerId)
16577e860f15SJohn Edward Broadbent {
16583ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
165945ca1b86SEd Tanous     {
166045ca1b86SEd Tanous         return;
166145ca1b86SEd Tanous     }
1662253f11b8SEd Tanous 
1663253f11b8SEd Tanous     if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1664253f11b8SEd Tanous     {
1665253f11b8SEd Tanous         messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1666253f11b8SEd Tanous         return;
1667253f11b8SEd Tanous     }
1668253f11b8SEd Tanous 
1669fdd26906SClaire Weinan     getDumpServiceInfo(asyncResp, dumpType);
1670fdd26906SClaire Weinan }
1671c9bb6861Sraviteja-b 
167222d268cbSEd Tanous inline void handleLogServicesDumpServiceComputerSystemGet(
167322d268cbSEd Tanous     crow::App& app, const crow::Request& req,
167422d268cbSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
167522d268cbSEd Tanous     const std::string& chassisId)
167622d268cbSEd Tanous {
167722d268cbSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
167822d268cbSEd Tanous     {
167922d268cbSEd Tanous         return;
168022d268cbSEd Tanous     }
1681253f11b8SEd Tanous     if (chassisId != BMCWEB_REDFISH_SYSTEM_URI_NAME)
168222d268cbSEd Tanous     {
168322d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem", chassisId);
168422d268cbSEd Tanous         return;
168522d268cbSEd Tanous     }
168622d268cbSEd Tanous     getDumpServiceInfo(asyncResp, "System");
168722d268cbSEd Tanous }
168822d268cbSEd Tanous 
1689fdd26906SClaire Weinan inline void handleLogServicesDumpEntriesCollectionGet(
1690fdd26906SClaire Weinan     crow::App& app, const std::string& dumpType, const crow::Request& req,
1691253f11b8SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1692253f11b8SEd Tanous     const std::string& managerId)
1693fdd26906SClaire Weinan {
1694fdd26906SClaire Weinan     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1695fdd26906SClaire Weinan     {
1696fdd26906SClaire Weinan         return;
1697fdd26906SClaire Weinan     }
1698253f11b8SEd Tanous 
1699253f11b8SEd Tanous     if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1700253f11b8SEd Tanous     {
1701253f11b8SEd Tanous         messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1702253f11b8SEd Tanous         return;
1703253f11b8SEd Tanous     }
1704fdd26906SClaire Weinan     getDumpEntryCollection(asyncResp, dumpType);
1705fdd26906SClaire Weinan }
1706fdd26906SClaire Weinan 
170722d268cbSEd Tanous inline void handleLogServicesDumpEntriesCollectionComputerSystemGet(
170822d268cbSEd Tanous     crow::App& app, const crow::Request& req,
170922d268cbSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
171022d268cbSEd Tanous     const std::string& chassisId)
171122d268cbSEd Tanous {
171222d268cbSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
171322d268cbSEd Tanous     {
171422d268cbSEd Tanous         return;
171522d268cbSEd Tanous     }
1716253f11b8SEd Tanous     if (chassisId != BMCWEB_REDFISH_SYSTEM_URI_NAME)
171722d268cbSEd Tanous     {
171822d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem", chassisId);
171922d268cbSEd Tanous         return;
172022d268cbSEd Tanous     }
172122d268cbSEd Tanous     getDumpEntryCollection(asyncResp, "System");
172222d268cbSEd Tanous }
172322d268cbSEd Tanous 
1724fdd26906SClaire Weinan inline void handleLogServicesDumpEntryGet(
1725fdd26906SClaire Weinan     crow::App& app, const std::string& dumpType, const crow::Request& req,
1726fdd26906SClaire Weinan     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1727253f11b8SEd Tanous     const std::string& managerId, const std::string& dumpId)
1728fdd26906SClaire Weinan {
1729fdd26906SClaire Weinan     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1730fdd26906SClaire Weinan     {
1731fdd26906SClaire Weinan         return;
1732fdd26906SClaire Weinan     }
1733253f11b8SEd Tanous     if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1734253f11b8SEd Tanous     {
1735253f11b8SEd Tanous         messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1736253f11b8SEd Tanous         return;
1737253f11b8SEd Tanous     }
1738fdd26906SClaire Weinan     getDumpEntryById(asyncResp, dumpId, dumpType);
1739fdd26906SClaire Weinan }
1740168d1b1aSCarson Labrado 
174122d268cbSEd Tanous inline void handleLogServicesDumpEntryComputerSystemGet(
174222d268cbSEd Tanous     crow::App& app, const crow::Request& req,
174322d268cbSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
174422d268cbSEd Tanous     const std::string& chassisId, const std::string& dumpId)
174522d268cbSEd Tanous {
174622d268cbSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
174722d268cbSEd Tanous     {
174822d268cbSEd Tanous         return;
174922d268cbSEd Tanous     }
1750253f11b8SEd Tanous     if (chassisId != BMCWEB_REDFISH_SYSTEM_URI_NAME)
175122d268cbSEd Tanous     {
175222d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem", chassisId);
175322d268cbSEd Tanous         return;
175422d268cbSEd Tanous     }
175522d268cbSEd Tanous     getDumpEntryById(asyncResp, dumpId, "System");
175622d268cbSEd Tanous }
1757fdd26906SClaire Weinan 
1758fdd26906SClaire Weinan inline void handleLogServicesDumpEntryDelete(
1759fdd26906SClaire Weinan     crow::App& app, const std::string& dumpType, const crow::Request& req,
1760fdd26906SClaire Weinan     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1761253f11b8SEd Tanous     const std::string& managerId, const std::string& dumpId)
1762fdd26906SClaire Weinan {
1763fdd26906SClaire Weinan     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1764fdd26906SClaire Weinan     {
1765fdd26906SClaire Weinan         return;
1766fdd26906SClaire Weinan     }
1767253f11b8SEd Tanous 
1768253f11b8SEd Tanous     if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1769253f11b8SEd Tanous     {
1770253f11b8SEd Tanous         messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1771253f11b8SEd Tanous         return;
1772253f11b8SEd Tanous     }
1773fdd26906SClaire Weinan     deleteDumpEntry(asyncResp, dumpId, dumpType);
1774fdd26906SClaire Weinan }
1775fdd26906SClaire Weinan 
177622d268cbSEd Tanous inline void handleLogServicesDumpEntryComputerSystemDelete(
177722d268cbSEd Tanous     crow::App& app, const crow::Request& req,
177822d268cbSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
177922d268cbSEd Tanous     const std::string& chassisId, const std::string& dumpId)
178022d268cbSEd Tanous {
178122d268cbSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
178222d268cbSEd Tanous     {
178322d268cbSEd Tanous         return;
178422d268cbSEd Tanous     }
1785253f11b8SEd Tanous     if (chassisId != BMCWEB_REDFISH_SYSTEM_URI_NAME)
178622d268cbSEd Tanous     {
178722d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem", chassisId);
178822d268cbSEd Tanous         return;
178922d268cbSEd Tanous     }
179022d268cbSEd Tanous     deleteDumpEntry(asyncResp, dumpId, "System");
179122d268cbSEd Tanous }
179222d268cbSEd Tanous 
1793168d1b1aSCarson Labrado inline void handleLogServicesDumpEntryDownloadGet(
1794168d1b1aSCarson Labrado     crow::App& app, const std::string& dumpType, const crow::Request& req,
1795168d1b1aSCarson Labrado     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1796253f11b8SEd Tanous     const std::string& managerId, const std::string& dumpId)
1797168d1b1aSCarson Labrado {
1798168d1b1aSCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1799168d1b1aSCarson Labrado     {
1800168d1b1aSCarson Labrado         return;
1801168d1b1aSCarson Labrado     }
1802253f11b8SEd Tanous 
1803253f11b8SEd Tanous     if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1804253f11b8SEd Tanous     {
1805253f11b8SEd Tanous         messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1806253f11b8SEd Tanous         return;
1807253f11b8SEd Tanous     }
1808168d1b1aSCarson Labrado     downloadDumpEntry(asyncResp, dumpId, dumpType);
1809168d1b1aSCarson Labrado }
1810168d1b1aSCarson Labrado 
1811168d1b1aSCarson Labrado inline void handleDBusEventLogEntryDownloadGet(
1812168d1b1aSCarson Labrado     crow::App& app, const std::string& dumpType, const crow::Request& req,
1813168d1b1aSCarson Labrado     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1814168d1b1aSCarson Labrado     const std::string& systemName, const std::string& entryID)
1815168d1b1aSCarson Labrado {
1816168d1b1aSCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1817168d1b1aSCarson Labrado     {
1818168d1b1aSCarson Labrado         return;
1819168d1b1aSCarson Labrado     }
1820168d1b1aSCarson Labrado     if (!http_helpers::isContentTypeAllowed(
1821168d1b1aSCarson Labrado             req.getHeaderValue("Accept"),
1822168d1b1aSCarson Labrado             http_helpers::ContentType::OctetStream, true))
1823168d1b1aSCarson Labrado     {
1824168d1b1aSCarson Labrado         asyncResp->res.result(boost::beast::http::status::bad_request);
1825168d1b1aSCarson Labrado         return;
1826168d1b1aSCarson Labrado     }
1827168d1b1aSCarson Labrado     downloadEventLogEntry(asyncResp, systemName, entryID, dumpType);
1828168d1b1aSCarson Labrado }
1829168d1b1aSCarson Labrado 
1830fdd26906SClaire Weinan inline void handleLogServicesDumpCollectDiagnosticDataPost(
1831fdd26906SClaire Weinan     crow::App& app, const std::string& dumpType, const crow::Request& req,
1832253f11b8SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1833253f11b8SEd Tanous     const std::string& managerId)
1834fdd26906SClaire Weinan {
1835fdd26906SClaire Weinan     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1836fdd26906SClaire Weinan     {
1837fdd26906SClaire Weinan         return;
1838fdd26906SClaire Weinan     }
1839253f11b8SEd Tanous     if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1840253f11b8SEd Tanous     {
1841253f11b8SEd Tanous         messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1842253f11b8SEd Tanous         return;
1843253f11b8SEd Tanous     }
1844253f11b8SEd Tanous 
1845fdd26906SClaire Weinan     createDump(asyncResp, req, dumpType);
1846fdd26906SClaire Weinan }
1847fdd26906SClaire Weinan 
184822d268cbSEd Tanous inline void handleLogServicesDumpCollectDiagnosticDataComputerSystemPost(
184922d268cbSEd Tanous     crow::App& app, const crow::Request& req,
185022d268cbSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
18517f3e84a1SEd Tanous     const std::string& systemName)
185222d268cbSEd Tanous {
185322d268cbSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
185422d268cbSEd Tanous     {
185522d268cbSEd Tanous         return;
185622d268cbSEd Tanous     }
18577f3e84a1SEd Tanous 
185825b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
185922d268cbSEd Tanous     {
18607f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
18617f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
18627f3e84a1SEd Tanous                                    systemName);
18637f3e84a1SEd Tanous         return;
18647f3e84a1SEd Tanous     }
1865253f11b8SEd Tanous     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
18667f3e84a1SEd Tanous     {
18677f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
18687f3e84a1SEd Tanous                                    systemName);
186922d268cbSEd Tanous         return;
187022d268cbSEd Tanous     }
187122d268cbSEd Tanous     createDump(asyncResp, req, "System");
187222d268cbSEd Tanous }
187322d268cbSEd Tanous 
1874fdd26906SClaire Weinan inline void handleLogServicesDumpClearLogPost(
1875fdd26906SClaire Weinan     crow::App& app, const std::string& dumpType, const crow::Request& req,
1876253f11b8SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1877253f11b8SEd Tanous     const std::string& managerId)
1878fdd26906SClaire Weinan {
1879fdd26906SClaire Weinan     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1880fdd26906SClaire Weinan     {
1881fdd26906SClaire Weinan         return;
1882fdd26906SClaire Weinan     }
1883253f11b8SEd Tanous 
1884253f11b8SEd Tanous     if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1885253f11b8SEd Tanous     {
1886253f11b8SEd Tanous         messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1887253f11b8SEd Tanous         return;
1888253f11b8SEd Tanous     }
1889fdd26906SClaire Weinan     clearDump(asyncResp, dumpType);
1890fdd26906SClaire Weinan }
1891fdd26906SClaire Weinan 
189222d268cbSEd Tanous inline void handleLogServicesDumpClearLogComputerSystemPost(
189322d268cbSEd Tanous     crow::App& app, const crow::Request& req,
189422d268cbSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
18957f3e84a1SEd Tanous     const std::string& systemName)
189622d268cbSEd Tanous {
189722d268cbSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
189822d268cbSEd Tanous     {
189922d268cbSEd Tanous         return;
190022d268cbSEd Tanous     }
190125b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
190222d268cbSEd Tanous     {
19037f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
19047f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
19057f3e84a1SEd Tanous                                    systemName);
19067f3e84a1SEd Tanous         return;
19077f3e84a1SEd Tanous     }
1908253f11b8SEd Tanous     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
19097f3e84a1SEd Tanous     {
19107f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
19117f3e84a1SEd Tanous                                    systemName);
191222d268cbSEd Tanous         return;
191322d268cbSEd Tanous     }
191422d268cbSEd Tanous     clearDump(asyncResp, "System");
191522d268cbSEd Tanous }
191622d268cbSEd Tanous 
1917fdd26906SClaire Weinan inline void requestRoutesBMCDumpService(App& app)
1918fdd26906SClaire Weinan {
1919253f11b8SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/LogServices/Dump/")
1920fdd26906SClaire Weinan         .privileges(redfish::privileges::getLogService)
1921fdd26906SClaire Weinan         .methods(boost::beast::http::verb::get)(std::bind_front(
1922fdd26906SClaire Weinan             handleLogServicesDumpServiceGet, std::ref(app), "BMC"));
1923fdd26906SClaire Weinan }
1924fdd26906SClaire Weinan 
1925fdd26906SClaire Weinan inline void requestRoutesBMCDumpEntryCollection(App& app)
1926fdd26906SClaire Weinan {
1927253f11b8SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/LogServices/Dump/Entries/")
1928fdd26906SClaire Weinan         .privileges(redfish::privileges::getLogEntryCollection)
1929fdd26906SClaire Weinan         .methods(boost::beast::http::verb::get)(std::bind_front(
1930fdd26906SClaire Weinan             handleLogServicesDumpEntriesCollectionGet, std::ref(app), "BMC"));
1931c9bb6861Sraviteja-b }
1932c9bb6861Sraviteja-b 
19337e860f15SJohn Edward Broadbent inline void requestRoutesBMCDumpEntry(App& app)
1934c9bb6861Sraviteja-b {
19357e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app,
1936253f11b8SEd Tanous                  "/redfish/v1/Managers/<str>/LogServices/Dump/Entries/<str>/")
1937ed398213SEd Tanous         .privileges(redfish::privileges::getLogEntry)
1938fdd26906SClaire Weinan         .methods(boost::beast::http::verb::get)(std::bind_front(
1939fdd26906SClaire Weinan             handleLogServicesDumpEntryGet, std::ref(app), "BMC"));
1940fdd26906SClaire Weinan 
19417e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app,
1942253f11b8SEd Tanous                  "/redfish/v1/Managers/<str>/LogServices/Dump/Entries/<str>/")
1943ed398213SEd Tanous         .privileges(redfish::privileges::deleteLogEntry)
1944fdd26906SClaire Weinan         .methods(boost::beast::http::verb::delete_)(std::bind_front(
1945fdd26906SClaire Weinan             handleLogServicesDumpEntryDelete, std::ref(app), "BMC"));
1946c9bb6861Sraviteja-b }
1947c9bb6861Sraviteja-b 
1948168d1b1aSCarson Labrado inline void requestRoutesBMCDumpEntryDownload(App& app)
1949168d1b1aSCarson Labrado {
1950168d1b1aSCarson Labrado     BMCWEB_ROUTE(
1951168d1b1aSCarson Labrado         app,
1952253f11b8SEd Tanous         "/redfish/v1/Managers/<str>/LogServices/Dump/Entries/<str>/attachment/")
1953168d1b1aSCarson Labrado         .privileges(redfish::privileges::getLogEntry)
1954168d1b1aSCarson Labrado         .methods(boost::beast::http::verb::get)(std::bind_front(
1955168d1b1aSCarson Labrado             handleLogServicesDumpEntryDownloadGet, std::ref(app), "BMC"));
1956168d1b1aSCarson Labrado }
1957168d1b1aSCarson Labrado 
19587e860f15SJohn Edward Broadbent inline void requestRoutesBMCDumpCreate(App& app)
1959c9bb6861Sraviteja-b {
19600fda0f12SGeorge Liu     BMCWEB_ROUTE(
19610fda0f12SGeorge Liu         app,
1962253f11b8SEd Tanous         "/redfish/v1/Managers/<str>/LogServices/Dump/Actions/LogService.CollectDiagnosticData/")
1963ed398213SEd Tanous         .privileges(redfish::privileges::postLogService)
19647e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::post)(
1965fdd26906SClaire Weinan             std::bind_front(handleLogServicesDumpCollectDiagnosticDataPost,
1966fdd26906SClaire Weinan                             std::ref(app), "BMC"));
1967a43be80fSAsmitha Karunanithi }
1968a43be80fSAsmitha Karunanithi 
19697e860f15SJohn Edward Broadbent inline void requestRoutesBMCDumpClear(App& app)
197080319af1SAsmitha Karunanithi {
19710fda0f12SGeorge Liu     BMCWEB_ROUTE(
19720fda0f12SGeorge Liu         app,
1973253f11b8SEd Tanous         "/redfish/v1/Managers/<str>/LogServices/Dump/Actions/LogService.ClearLog/")
1974ed398213SEd Tanous         .privileges(redfish::privileges::postLogService)
1975fdd26906SClaire Weinan         .methods(boost::beast::http::verb::post)(std::bind_front(
1976fdd26906SClaire Weinan             handleLogServicesDumpClearLogPost, std::ref(app), "BMC"));
197745ca1b86SEd Tanous }
1978fdd26906SClaire Weinan 
1979168d1b1aSCarson Labrado inline void requestRoutesDBusEventLogEntryDownload(App& app)
1980168d1b1aSCarson Labrado {
1981168d1b1aSCarson Labrado     BMCWEB_ROUTE(
1982168d1b1aSCarson Labrado         app,
19839e9d99daSRavi Teja         "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/<str>/attachment/")
1984168d1b1aSCarson Labrado         .privileges(redfish::privileges::getLogEntry)
1985168d1b1aSCarson Labrado         .methods(boost::beast::http::verb::get)(std::bind_front(
1986168d1b1aSCarson Labrado             handleDBusEventLogEntryDownloadGet, std::ref(app), "System"));
1987168d1b1aSCarson Labrado }
1988168d1b1aSCarson Labrado 
1989fdd26906SClaire Weinan inline void requestRoutesFaultLogDumpService(App& app)
1990fdd26906SClaire Weinan {
1991253f11b8SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/LogServices/FaultLog/")
1992fdd26906SClaire Weinan         .privileges(redfish::privileges::getLogService)
1993fdd26906SClaire Weinan         .methods(boost::beast::http::verb::get)(std::bind_front(
1994fdd26906SClaire Weinan             handleLogServicesDumpServiceGet, std::ref(app), "FaultLog"));
1995fdd26906SClaire Weinan }
1996fdd26906SClaire Weinan 
1997fdd26906SClaire Weinan inline void requestRoutesFaultLogDumpEntryCollection(App& app)
1998fdd26906SClaire Weinan {
1999253f11b8SEd Tanous     BMCWEB_ROUTE(app,
2000253f11b8SEd Tanous                  "/redfish/v1/Managers/<str>/LogServices/FaultLog/Entries/")
2001fdd26906SClaire Weinan         .privileges(redfish::privileges::getLogEntryCollection)
2002fdd26906SClaire Weinan         .methods(boost::beast::http::verb::get)(
2003fdd26906SClaire Weinan             std::bind_front(handleLogServicesDumpEntriesCollectionGet,
2004fdd26906SClaire Weinan                             std::ref(app), "FaultLog"));
2005fdd26906SClaire Weinan }
2006fdd26906SClaire Weinan 
2007fdd26906SClaire Weinan inline void requestRoutesFaultLogDumpEntry(App& app)
2008fdd26906SClaire Weinan {
2009253f11b8SEd Tanous     BMCWEB_ROUTE(
2010253f11b8SEd Tanous         app, "/redfish/v1/Managers/<str>/LogServices/FaultLog/Entries/<str>/")
2011fdd26906SClaire Weinan         .privileges(redfish::privileges::getLogEntry)
2012fdd26906SClaire Weinan         .methods(boost::beast::http::verb::get)(std::bind_front(
2013fdd26906SClaire Weinan             handleLogServicesDumpEntryGet, std::ref(app), "FaultLog"));
2014fdd26906SClaire Weinan 
2015253f11b8SEd Tanous     BMCWEB_ROUTE(
2016253f11b8SEd Tanous         app, "/redfish/v1/Managers/<str>/LogServices/FaultLog/Entries/<str>/")
2017fdd26906SClaire Weinan         .privileges(redfish::privileges::deleteLogEntry)
2018fdd26906SClaire Weinan         .methods(boost::beast::http::verb::delete_)(std::bind_front(
2019fdd26906SClaire Weinan             handleLogServicesDumpEntryDelete, std::ref(app), "FaultLog"));
2020fdd26906SClaire Weinan }
2021fdd26906SClaire Weinan 
2022fdd26906SClaire Weinan inline void requestRoutesFaultLogDumpClear(App& app)
2023fdd26906SClaire Weinan {
2024fdd26906SClaire Weinan     BMCWEB_ROUTE(
2025fdd26906SClaire Weinan         app,
2026253f11b8SEd Tanous         "/redfish/v1/Managers/<str>/LogServices/FaultLog/Actions/LogService.ClearLog/")
2027fdd26906SClaire Weinan         .privileges(redfish::privileges::postLogService)
2028fdd26906SClaire Weinan         .methods(boost::beast::http::verb::post)(std::bind_front(
2029fdd26906SClaire Weinan             handleLogServicesDumpClearLogPost, std::ref(app), "FaultLog"));
20305cb1dd27SAsmitha Karunanithi }
20315cb1dd27SAsmitha Karunanithi 
20327e860f15SJohn Edward Broadbent inline void requestRoutesSystemDumpService(App& app)
20335cb1dd27SAsmitha Karunanithi {
203422d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/Dump/")
2035ed398213SEd Tanous         .privileges(redfish::privileges::getLogService)
20366ab9ad54SClaire Weinan         .methods(boost::beast::http::verb::get)(std::bind_front(
203722d268cbSEd Tanous             handleLogServicesDumpServiceComputerSystemGet, std::ref(app)));
20385cb1dd27SAsmitha Karunanithi }
20395cb1dd27SAsmitha Karunanithi 
20407e860f15SJohn Edward Broadbent inline void requestRoutesSystemDumpEntryCollection(App& app)
20417e860f15SJohn Edward Broadbent {
204222d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/Dump/Entries/")
2043ed398213SEd Tanous         .privileges(redfish::privileges::getLogEntryCollection)
204422d268cbSEd Tanous         .methods(boost::beast::http::verb::get)(std::bind_front(
204522d268cbSEd Tanous             handleLogServicesDumpEntriesCollectionComputerSystemGet,
204622d268cbSEd Tanous             std::ref(app)));
20475cb1dd27SAsmitha Karunanithi }
20485cb1dd27SAsmitha Karunanithi 
20497e860f15SJohn Edward Broadbent inline void requestRoutesSystemDumpEntry(App& app)
20505cb1dd27SAsmitha Karunanithi {
20517e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app,
205222d268cbSEd Tanous                  "/redfish/v1/Systems/<str>/LogServices/Dump/Entries/<str>/")
2053ed398213SEd Tanous         .privileges(redfish::privileges::getLogEntry)
20546ab9ad54SClaire Weinan         .methods(boost::beast::http::verb::get)(std::bind_front(
205522d268cbSEd Tanous             handleLogServicesDumpEntryComputerSystemGet, std::ref(app)));
20568d1b46d7Szhanghch05 
20577e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app,
205822d268cbSEd Tanous                  "/redfish/v1/Systems/<str>/LogServices/Dump/Entries/<str>/")
2059ed398213SEd Tanous         .privileges(redfish::privileges::deleteLogEntry)
20606ab9ad54SClaire Weinan         .methods(boost::beast::http::verb::delete_)(std::bind_front(
206122d268cbSEd Tanous             handleLogServicesDumpEntryComputerSystemDelete, std::ref(app)));
20625cb1dd27SAsmitha Karunanithi }
2063c9bb6861Sraviteja-b 
20647e860f15SJohn Edward Broadbent inline void requestRoutesSystemDumpCreate(App& app)
2065c9bb6861Sraviteja-b {
20660fda0f12SGeorge Liu     BMCWEB_ROUTE(
20670fda0f12SGeorge Liu         app,
206822d268cbSEd Tanous         "/redfish/v1/Systems/<str>/LogServices/Dump/Actions/LogService.CollectDiagnosticData/")
2069fff6a4d3SAbhishek Patel         .privileges(redfish::privileges::
2070fff6a4d3SAbhishek Patel                         postLogServiceSubOverComputerSystemLogServiceCollection)
207122d268cbSEd Tanous         .methods(boost::beast::http::verb::post)(std::bind_front(
207222d268cbSEd Tanous             handleLogServicesDumpCollectDiagnosticDataComputerSystemPost,
207322d268cbSEd Tanous             std::ref(app)));
2074a43be80fSAsmitha Karunanithi }
2075a43be80fSAsmitha Karunanithi 
20767e860f15SJohn Edward Broadbent inline void requestRoutesSystemDumpClear(App& app)
2077a43be80fSAsmitha Karunanithi {
20780fda0f12SGeorge Liu     BMCWEB_ROUTE(
20790fda0f12SGeorge Liu         app,
208022d268cbSEd Tanous         "/redfish/v1/Systems/<str>/LogServices/Dump/Actions/LogService.ClearLog/")
2081fff6a4d3SAbhishek Patel         .privileges(redfish::privileges::
2082fff6a4d3SAbhishek Patel                         postLogServiceSubOverComputerSystemLogServiceCollection)
20836ab9ad54SClaire Weinan         .methods(boost::beast::http::verb::post)(std::bind_front(
208422d268cbSEd Tanous             handleLogServicesDumpClearLogComputerSystemPost, std::ref(app)));
2085013487e5Sraviteja-b }
2086013487e5Sraviteja-b 
20877e860f15SJohn Edward Broadbent inline void requestRoutesCrashdumpService(App& app)
20881da66f75SEd Tanous {
20891da66f75SEd Tanous     /**
20901da66f75SEd Tanous      * Functions triggers appropriate requests on DBus
20911da66f75SEd Tanous      */
209222d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/Crashdump/")
209350d9f38aSMyung Bae         .privileges(redfish::privileges::getLogService)
2094bd79bce8SPatrick Williams         .methods(
2095bd79bce8SPatrick Williams             boost::beast::http::verb::
2096bd79bce8SPatrick Williams                 get)([&app](const crow::Request& req,
209722d268cbSEd Tanous                             const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
209822d268cbSEd Tanous                             const std::string& systemName) {
20993ba00073SCarson Labrado             if (!redfish::setUpRedfishRoute(app, req, asyncResp))
210045ca1b86SEd Tanous             {
210145ca1b86SEd Tanous                 return;
210245ca1b86SEd Tanous             }
210325b54dbaSEd Tanous             if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
21047f3e84a1SEd Tanous             {
21057f3e84a1SEd Tanous                 // Option currently returns no systems.  TBD
21067f3e84a1SEd Tanous                 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
21077f3e84a1SEd Tanous                                            systemName);
21087f3e84a1SEd Tanous                 return;
21097f3e84a1SEd Tanous             }
2110253f11b8SEd Tanous             if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
211122d268cbSEd Tanous             {
211222d268cbSEd Tanous                 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
211322d268cbSEd Tanous                                            systemName);
211422d268cbSEd Tanous                 return;
211522d268cbSEd Tanous             }
211622d268cbSEd Tanous 
21177e860f15SJohn Edward Broadbent             // Copy over the static data to include the entries added by
21187e860f15SJohn Edward Broadbent             // SubRoute
21190f74e643SEd Tanous             asyncResp->res.jsonValue["@odata.id"] =
2120253f11b8SEd Tanous                 std::format("/redfish/v1/Systems/{}/LogServices/Crashdump",
2121253f11b8SEd Tanous                             BMCWEB_REDFISH_SYSTEM_URI_NAME);
2122e1f26343SJason M. Bills             asyncResp->res.jsonValue["@odata.type"] =
21238e6c099aSJason M. Bills                 "#LogService.v1_2_0.LogService";
21244f50ae4bSGunnar Mills             asyncResp->res.jsonValue["Name"] = "Open BMC Oem Crashdump Service";
21254f50ae4bSGunnar Mills             asyncResp->res.jsonValue["Description"] = "Oem Crashdump Service";
212615b89725SV-Sanjana             asyncResp->res.jsonValue["Id"] = "Crashdump";
2127539d8c6bSEd Tanous             asyncResp->res.jsonValue["OverWritePolicy"] =
2128539d8c6bSEd Tanous                 log_service::OverWritePolicy::WrapsWhenFull;
2129e1f26343SJason M. Bills             asyncResp->res.jsonValue["MaxNumberOfRecords"] = 3;
21307c8c4058STejas Patil 
21317c8c4058STejas Patil             std::pair<std::string, std::string> redfishDateTimeOffset =
21322b82937eSEd Tanous                 redfish::time_utils::getDateTimeOffsetNow();
21337c8c4058STejas Patil             asyncResp->res.jsonValue["DateTime"] = redfishDateTimeOffset.first;
21347c8c4058STejas Patil             asyncResp->res.jsonValue["DateTimeLocalOffset"] =
21357c8c4058STejas Patil                 redfishDateTimeOffset.second;
21367c8c4058STejas Patil 
2137bd79bce8SPatrick Williams             asyncResp->res.jsonValue["Entries"]["@odata.id"] = std::format(
2138bd79bce8SPatrick Williams                 "/redfish/v1/Systems/{}/LogServices/Crashdump/Entries",
2139253f11b8SEd Tanous                 BMCWEB_REDFISH_SYSTEM_URI_NAME);
2140253f11b8SEd Tanous             asyncResp->res.jsonValue["Actions"]["#LogService.ClearLog"]
2141253f11b8SEd Tanous                                     ["target"] = std::format(
2142253f11b8SEd Tanous                 "/redfish/v1/Systems/{}/LogServices/Crashdump/Actions/LogService.ClearLog",
2143253f11b8SEd Tanous                 BMCWEB_REDFISH_SYSTEM_URI_NAME);
2144bd79bce8SPatrick Williams             asyncResp->res
2145bd79bce8SPatrick Williams                 .jsonValue["Actions"]["#LogService.CollectDiagnosticData"]
2146253f11b8SEd Tanous                           ["target"] = std::format(
2147253f11b8SEd Tanous                 "/redfish/v1/Systems/{}/LogServices/Crashdump/Actions/LogService.CollectDiagnosticData",
2148253f11b8SEd Tanous                 BMCWEB_REDFISH_SYSTEM_URI_NAME);
2149*08fad5d9SCorey Ethington 
2150*08fad5d9SCorey Ethington             etag_utils::setEtagOmitDateTimeHandler(asyncResp);
21517e860f15SJohn Edward Broadbent         });
21521da66f75SEd Tanous }
21531da66f75SEd Tanous 
21548e4736b3SEd Tanous inline void requestRoutesCrashdumpClear(App& app)
21555b61b5e8SJason M. Bills {
21560fda0f12SGeorge Liu     BMCWEB_ROUTE(
21570fda0f12SGeorge Liu         app,
215822d268cbSEd Tanous         "/redfish/v1/Systems/<str>/LogServices/Crashdump/Actions/LogService.ClearLog/")
215950d9f38aSMyung Bae         .privileges(redfish::privileges::
216050d9f38aSMyung Bae                         postLogServiceSubOverComputerSystemLogServiceCollection)
21617e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::post)(
216245ca1b86SEd Tanous             [&app](const crow::Request& req,
216322d268cbSEd Tanous                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
216422d268cbSEd Tanous                    const std::string& systemName) {
21653ba00073SCarson Labrado                 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
216645ca1b86SEd Tanous                 {
216745ca1b86SEd Tanous                     return;
216845ca1b86SEd Tanous                 }
216925b54dbaSEd Tanous                 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
21707f3e84a1SEd Tanous                 {
21717f3e84a1SEd Tanous                     // Option currently returns no systems.  TBD
21727f3e84a1SEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
21737f3e84a1SEd Tanous                                                systemName);
21747f3e84a1SEd Tanous                     return;
21757f3e84a1SEd Tanous                 }
2176253f11b8SEd Tanous                 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
217722d268cbSEd Tanous                 {
217822d268cbSEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
217922d268cbSEd Tanous                                                systemName);
218022d268cbSEd Tanous                     return;
218122d268cbSEd Tanous                 }
2182177612aaSEd Tanous                 dbus::utility::async_method_call(
2183177612aaSEd Tanous                     asyncResp,
21845e7e2dc5SEd Tanous                     [asyncResp](const boost::system::error_code& ec,
2185cb13a392SEd Tanous                                 const std::string&) {
21865b61b5e8SJason M. Bills                         if (ec)
21875b61b5e8SJason M. Bills                         {
21885b61b5e8SJason M. Bills                             messages::internalError(asyncResp->res);
21895b61b5e8SJason M. Bills                             return;
21905b61b5e8SJason M. Bills                         }
21915b61b5e8SJason M. Bills                         messages::success(asyncResp->res);
21925b61b5e8SJason M. Bills                     },
2193bd79bce8SPatrick Williams                     crashdumpObject, crashdumpPath, deleteAllInterface,
2194bd79bce8SPatrick Williams                     "DeleteAll");
21957e860f15SJohn Edward Broadbent             });
21965b61b5e8SJason M. Bills }
21975b61b5e8SJason M. Bills 
2198504af5a0SPatrick Williams inline void logCrashdumpEntry(
2199504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
22008d1b46d7Szhanghch05     const std::string& logID, nlohmann::json& logEntryJson)
2201e855dd28SJason M. Bills {
2202043a0536SJohnathan Mantey     auto getStoredLogCallback =
2203b9d36b47SEd Tanous         [asyncResp, logID,
22045e7e2dc5SEd Tanous          &logEntryJson](const boost::system::error_code& ec,
2205b9d36b47SEd Tanous                         const dbus::utility::DBusPropertiesMap& params) {
2206e855dd28SJason M. Bills             if (ec)
2207e855dd28SJason M. Bills             {
220862598e31SEd Tanous                 BMCWEB_LOG_DEBUG("failed to get log ec: {}", ec.message());
22091ddcf01aSJason M. Bills                 if (ec.value() ==
22101ddcf01aSJason M. Bills                     boost::system::linux_error::bad_request_descriptor)
22111ddcf01aSJason M. Bills                 {
2212bd79bce8SPatrick Williams                     messages::resourceNotFound(asyncResp->res, "LogEntry",
2213bd79bce8SPatrick Williams                                                logID);
22141ddcf01aSJason M. Bills                 }
22151ddcf01aSJason M. Bills                 else
22161ddcf01aSJason M. Bills                 {
2217e855dd28SJason M. Bills                     messages::internalError(asyncResp->res);
22181ddcf01aSJason M. Bills                 }
2219e855dd28SJason M. Bills                 return;
2220e855dd28SJason M. Bills             }
2221043a0536SJohnathan Mantey 
2222043a0536SJohnathan Mantey             std::string timestamp{};
2223043a0536SJohnathan Mantey             std::string filename{};
2224043a0536SJohnathan Mantey             std::string logfile{};
22252c70f800SEd Tanous             parseCrashdumpParameters(params, filename, timestamp, logfile);
2226043a0536SJohnathan Mantey 
2227043a0536SJohnathan Mantey             if (filename.empty() || timestamp.empty())
2228e855dd28SJason M. Bills             {
22299db4ba25SJiaqing Zhao                 messages::resourceNotFound(asyncResp->res, "LogEntry", logID);
2230e855dd28SJason M. Bills                 return;
2231e855dd28SJason M. Bills             }
2232e855dd28SJason M. Bills 
2233043a0536SJohnathan Mantey             std::string crashdumpURI =
2234bd79bce8SPatrick Williams                 std::format(
2235bd79bce8SPatrick Williams                     "/redfish/v1/Systems/{}/LogServices/Crashdump/Entries/",
2236253f11b8SEd Tanous                     BMCWEB_REDFISH_SYSTEM_URI_NAME) +
2237043a0536SJohnathan Mantey                 logID + "/" + filename;
223884afc48bSJason M. Bills             nlohmann::json::object_t logEntry;
22399c11a172SVijay Lobo             logEntry["@odata.type"] = "#LogEntry.v1_9_0.LogEntry";
2240ef4c65b7SEd Tanous             logEntry["@odata.id"] = boost::urls::format(
2241253f11b8SEd Tanous                 "/redfish/v1/Systems/{}/LogServices/Crashdump/Entries/{}",
2242253f11b8SEd Tanous                 BMCWEB_REDFISH_SYSTEM_URI_NAME, logID);
224384afc48bSJason M. Bills             logEntry["Name"] = "CPU Crashdump";
224484afc48bSJason M. Bills             logEntry["Id"] = logID;
2245539d8c6bSEd Tanous             logEntry["EntryType"] = log_entry::LogEntryType::Oem;
224684afc48bSJason M. Bills             logEntry["AdditionalDataURI"] = std::move(crashdumpURI);
224784afc48bSJason M. Bills             logEntry["DiagnosticDataType"] = "OEM";
224884afc48bSJason M. Bills             logEntry["OEMDiagnosticDataType"] = "PECICrashdump";
224984afc48bSJason M. Bills             logEntry["Created"] = std::move(timestamp);
22502b20ef6eSJason M. Bills 
22512b20ef6eSJason M. Bills             // If logEntryJson references an array of LogEntry resources
22522b20ef6eSJason M. Bills             // ('Members' list), then push this as a new entry, otherwise set it
22532b20ef6eSJason M. Bills             // directly
22542b20ef6eSJason M. Bills             if (logEntryJson.is_array())
22552b20ef6eSJason M. Bills             {
22562b20ef6eSJason M. Bills                 logEntryJson.push_back(logEntry);
22572b20ef6eSJason M. Bills                 asyncResp->res.jsonValue["Members@odata.count"] =
22582b20ef6eSJason M. Bills                     logEntryJson.size();
22592b20ef6eSJason M. Bills             }
22602b20ef6eSJason M. Bills             else
22612b20ef6eSJason M. Bills             {
2262d405bb51SJason M. Bills                 logEntryJson.update(logEntry);
22632b20ef6eSJason M. Bills             }
2264e855dd28SJason M. Bills         };
2265deae6a78SEd Tanous     dbus::utility::getAllProperties(
2266deae6a78SEd Tanous         crashdumpObject, crashdumpPath + std::string("/") + logID,
2267deae6a78SEd Tanous         crashdumpInterface, std::move(getStoredLogCallback));
2268e855dd28SJason M. Bills }
2269e855dd28SJason M. Bills 
22707e860f15SJohn Edward Broadbent inline void requestRoutesCrashdumpEntryCollection(App& app)
22711da66f75SEd Tanous {
22721da66f75SEd Tanous     /**
22731da66f75SEd Tanous      * Functions triggers appropriate requests on DBus
22741da66f75SEd Tanous      */
22757e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app,
227622d268cbSEd Tanous                  "/redfish/v1/Systems/<str>/LogServices/Crashdump/Entries/")
227750d9f38aSMyung Bae         .privileges(redfish::privileges::getLogEntryCollection)
2278bd79bce8SPatrick Williams         .methods(
2279bd79bce8SPatrick Williams             boost::beast::http::verb::
2280bd79bce8SPatrick Williams                 get)([&app](const crow::Request& req,
228122d268cbSEd Tanous                             const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
228222d268cbSEd Tanous                             const std::string& systemName) {
22833ba00073SCarson Labrado             if (!redfish::setUpRedfishRoute(app, req, asyncResp))
228445ca1b86SEd Tanous             {
228545ca1b86SEd Tanous                 return;
228645ca1b86SEd Tanous             }
228725b54dbaSEd Tanous             if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
22887f3e84a1SEd Tanous             {
22897f3e84a1SEd Tanous                 // Option currently returns no systems.  TBD
22907f3e84a1SEd Tanous                 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
22917f3e84a1SEd Tanous                                            systemName);
22927f3e84a1SEd Tanous                 return;
22937f3e84a1SEd Tanous             }
2294253f11b8SEd Tanous             if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
229522d268cbSEd Tanous             {
229622d268cbSEd Tanous                 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
229722d268cbSEd Tanous                                            systemName);
229822d268cbSEd Tanous                 return;
229922d268cbSEd Tanous             }
230022d268cbSEd Tanous 
23017a1dbc48SGeorge Liu             constexpr std::array<std::string_view, 1> interfaces = {
23027a1dbc48SGeorge Liu                 crashdumpInterface};
23037a1dbc48SGeorge Liu             dbus::utility::getSubTreePaths(
23047a1dbc48SGeorge Liu                 "/", 0, interfaces,
23057a1dbc48SGeorge Liu                 [asyncResp](const boost::system::error_code& ec,
23062b20ef6eSJason M. Bills                             const std::vector<std::string>& resp) {
23071da66f75SEd Tanous                     if (ec)
23081da66f75SEd Tanous                     {
23091da66f75SEd Tanous                         if (ec.value() !=
23101da66f75SEd Tanous                             boost::system::errc::no_such_file_or_directory)
23111da66f75SEd Tanous                         {
231262598e31SEd Tanous                             BMCWEB_LOG_DEBUG("failed to get entries ec: {}",
231362598e31SEd Tanous                                              ec.message());
2314f12894f8SJason M. Bills                             messages::internalError(asyncResp->res);
23151da66f75SEd Tanous                             return;
23161da66f75SEd Tanous                         }
23171da66f75SEd Tanous                     }
2318e1f26343SJason M. Bills                     asyncResp->res.jsonValue["@odata.type"] =
23191da66f75SEd Tanous                         "#LogEntryCollection.LogEntryCollection";
2320253f11b8SEd Tanous                     asyncResp->res.jsonValue["@odata.id"] = std::format(
2321253f11b8SEd Tanous                         "/redfish/v1/Systems/{}/LogServices/Crashdump/Entries",
2322253f11b8SEd Tanous                         BMCWEB_REDFISH_SYSTEM_URI_NAME);
2323bd79bce8SPatrick Williams                     asyncResp->res.jsonValue["Name"] =
2324bd79bce8SPatrick Williams                         "Open BMC Crashdump Entries";
2325e1f26343SJason M. Bills                     asyncResp->res.jsonValue["Description"] =
2326424c4176SJason M. Bills                         "Collection of Crashdump Entries";
2327bd79bce8SPatrick Williams                     asyncResp->res.jsonValue["Members"] =
2328bd79bce8SPatrick Williams                         nlohmann::json::array();
2329a2dd60a6SBrandon Kim                     asyncResp->res.jsonValue["Members@odata.count"] = 0;
23302b20ef6eSJason M. Bills 
23312b20ef6eSJason M. Bills                     for (const std::string& path : resp)
23321da66f75SEd Tanous                     {
23332b20ef6eSJason M. Bills                         const sdbusplus::message::object_path objPath(path);
2334e855dd28SJason M. Bills                         // Get the log ID
23352b20ef6eSJason M. Bills                         std::string logID = objPath.filename();
23362b20ef6eSJason M. Bills                         if (logID.empty())
23371da66f75SEd Tanous                         {
2338e855dd28SJason M. Bills                             continue;
23391da66f75SEd Tanous                         }
2340e855dd28SJason M. Bills                         // Add the log entry to the array
23412b20ef6eSJason M. Bills                         logCrashdumpEntry(asyncResp, logID,
23422b20ef6eSJason M. Bills                                           asyncResp->res.jsonValue["Members"]);
23431da66f75SEd Tanous                     }
23447a1dbc48SGeorge Liu                 });
23457e860f15SJohn Edward Broadbent         });
23461da66f75SEd Tanous }
23471da66f75SEd Tanous 
23487e860f15SJohn Edward Broadbent inline void requestRoutesCrashdumpEntry(App& app)
23491da66f75SEd Tanous {
23507e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(
235122d268cbSEd Tanous         app, "/redfish/v1/Systems/<str>/LogServices/Crashdump/Entries/<str>/")
235250d9f38aSMyung Bae         .privileges(redfish::privileges::getLogEntry)
23537e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
235445ca1b86SEd Tanous             [&app](const crow::Request& req,
23557e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
235622d268cbSEd Tanous                    const std::string& systemName, const std::string& param) {
23573ba00073SCarson Labrado                 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
235845ca1b86SEd Tanous                 {
235945ca1b86SEd Tanous                     return;
236045ca1b86SEd Tanous                 }
236125b54dbaSEd Tanous                 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
23627f3e84a1SEd Tanous                 {
23637f3e84a1SEd Tanous                     // Option currently returns no systems.  TBD
23647f3e84a1SEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
23657f3e84a1SEd Tanous                                                systemName);
23667f3e84a1SEd Tanous                     return;
23677f3e84a1SEd Tanous                 }
2368253f11b8SEd Tanous                 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
236922d268cbSEd Tanous                 {
237022d268cbSEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
237122d268cbSEd Tanous                                                systemName);
237222d268cbSEd Tanous                     return;
237322d268cbSEd Tanous                 }
23747e860f15SJohn Edward Broadbent                 const std::string& logID = param;
2375e855dd28SJason M. Bills                 logCrashdumpEntry(asyncResp, logID, asyncResp->res.jsonValue);
23767e860f15SJohn Edward Broadbent             });
2377e855dd28SJason M. Bills }
2378e855dd28SJason M. Bills 
23797e860f15SJohn Edward Broadbent inline void requestRoutesCrashdumpFile(App& app)
2380e855dd28SJason M. Bills {
23817e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(
23827e860f15SJohn Edward Broadbent         app,
238322d268cbSEd Tanous         "/redfish/v1/Systems/<str>/LogServices/Crashdump/Entries/<str>/<str>/")
2384ed398213SEd Tanous         .privileges(redfish::privileges::getLogEntry)
23857e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
2386a4ce114aSNan Zhou             [](const crow::Request& req,
23877e860f15SJohn Edward Broadbent                const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
238822d268cbSEd Tanous                const std::string& systemName, const std::string& logID,
238922d268cbSEd Tanous                const std::string& fileName) {
2390bd79bce8SPatrick Williams                 // Do not call getRedfishRoute here since the crashdump file is
2391bd79bce8SPatrick Williams                 // not a Redfish resource.
239222d268cbSEd Tanous 
239325b54dbaSEd Tanous                 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
23947f3e84a1SEd Tanous                 {
23957f3e84a1SEd Tanous                     // Option currently returns no systems.  TBD
23967f3e84a1SEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
23977f3e84a1SEd Tanous                                                systemName);
23987f3e84a1SEd Tanous                     return;
23997f3e84a1SEd Tanous                 }
2400253f11b8SEd Tanous                 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
240122d268cbSEd Tanous                 {
240222d268cbSEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
240322d268cbSEd Tanous                                                systemName);
240422d268cbSEd Tanous                     return;
240522d268cbSEd Tanous                 }
240622d268cbSEd Tanous 
2407043a0536SJohnathan Mantey                 auto getStoredLogCallback =
2408bd79bce8SPatrick Williams                     [asyncResp, logID, fileName,
2409bd79bce8SPatrick Williams                      url(boost::urls::url(req.url()))](
24105e7e2dc5SEd Tanous                         const boost::system::error_code& ec,
2411bd79bce8SPatrick Williams                         const std::vector<std::pair<
2412bd79bce8SPatrick Williams                             std::string, dbus::utility::DbusVariantType>>&
24137e860f15SJohn Edward Broadbent                             resp) {
24141da66f75SEd Tanous                         if (ec)
24151da66f75SEd Tanous                         {
2416bd79bce8SPatrick Williams                             BMCWEB_LOG_DEBUG("failed to get log ec: {}",
2417bd79bce8SPatrick Williams                                              ec.message());
2418f12894f8SJason M. Bills                             messages::internalError(asyncResp->res);
24191da66f75SEd Tanous                             return;
24201da66f75SEd Tanous                         }
2421e855dd28SJason M. Bills 
2422043a0536SJohnathan Mantey                         std::string dbusFilename{};
2423043a0536SJohnathan Mantey                         std::string dbusTimestamp{};
2424043a0536SJohnathan Mantey                         std::string dbusFilepath{};
2425043a0536SJohnathan Mantey 
2426bd79bce8SPatrick Williams                         parseCrashdumpParameters(resp, dbusFilename,
2427bd79bce8SPatrick Williams                                                  dbusTimestamp, dbusFilepath);
2428043a0536SJohnathan Mantey 
2429043a0536SJohnathan Mantey                         if (dbusFilename.empty() || dbusTimestamp.empty() ||
2430043a0536SJohnathan Mantey                             dbusFilepath.empty())
24311da66f75SEd Tanous                         {
2432bd79bce8SPatrick Williams                             messages::resourceNotFound(asyncResp->res,
2433bd79bce8SPatrick Williams                                                        "LogEntry", logID);
24341da66f75SEd Tanous                             return;
24351da66f75SEd Tanous                         }
2436e855dd28SJason M. Bills 
2437043a0536SJohnathan Mantey                         // Verify the file name parameter is correct
2438043a0536SJohnathan Mantey                         if (fileName != dbusFilename)
2439043a0536SJohnathan Mantey                         {
2440bd79bce8SPatrick Williams                             messages::resourceNotFound(asyncResp->res,
2441bd79bce8SPatrick Williams                                                        "LogEntry", logID);
2442043a0536SJohnathan Mantey                             return;
2443043a0536SJohnathan Mantey                         }
2444043a0536SJohnathan Mantey 
2445d51c61b4SMyung Bae                         if (asyncResp->res.openFile(dbusFilepath) !=
2446d51c61b4SMyung Bae                             crow::OpenCode::Success)
2447043a0536SJohnathan Mantey                         {
2448bd79bce8SPatrick Williams                             messages::resourceNotFound(asyncResp->res,
2449bd79bce8SPatrick Williams                                                        "LogEntry", logID);
2450043a0536SJohnathan Mantey                             return;
2451043a0536SJohnathan Mantey                         }
2452043a0536SJohnathan Mantey 
24537e860f15SJohn Edward Broadbent                         // Configure this to be a file download when accessed
24547e860f15SJohn Edward Broadbent                         // from a browser
2455d9f6c621SEd Tanous                         asyncResp->res.addHeader(
2456bd79bce8SPatrick Williams                             boost::beast::http::field::content_disposition,
2457bd79bce8SPatrick Williams                             "attachment");
24581da66f75SEd Tanous                     };
2459deae6a78SEd Tanous                 dbus::utility::getAllProperties(
2460d1bde9e5SKrzysztof Grobelny                     *crow::connections::systemBus, crashdumpObject,
2461bd79bce8SPatrick Williams                     crashdumpPath + std::string("/") + logID,
2462bd79bce8SPatrick Williams                     crashdumpInterface, std::move(getStoredLogCallback));
24637e860f15SJohn Edward Broadbent             });
24641da66f75SEd Tanous }
24651da66f75SEd Tanous 
2466c5a4c82aSJason M. Bills enum class OEMDiagnosticType
2467c5a4c82aSJason M. Bills {
2468c5a4c82aSJason M. Bills     onDemand,
2469c5a4c82aSJason M. Bills     telemetry,
2470c5a4c82aSJason M. Bills     invalid,
2471c5a4c82aSJason M. Bills };
2472c5a4c82aSJason M. Bills 
247326ccae32SEd Tanous inline OEMDiagnosticType getOEMDiagnosticType(std::string_view oemDiagStr)
2474c5a4c82aSJason M. Bills {
2475c5a4c82aSJason M. Bills     if (oemDiagStr == "OnDemand")
2476c5a4c82aSJason M. Bills     {
2477c5a4c82aSJason M. Bills         return OEMDiagnosticType::onDemand;
2478c5a4c82aSJason M. Bills     }
2479c5a4c82aSJason M. Bills     if (oemDiagStr == "Telemetry")
2480c5a4c82aSJason M. Bills     {
2481c5a4c82aSJason M. Bills         return OEMDiagnosticType::telemetry;
2482c5a4c82aSJason M. Bills     }
2483c5a4c82aSJason M. Bills 
2484c5a4c82aSJason M. Bills     return OEMDiagnosticType::invalid;
2485c5a4c82aSJason M. Bills }
2486c5a4c82aSJason M. Bills 
24877e860f15SJohn Edward Broadbent inline void requestRoutesCrashdumpCollect(App& app)
24881da66f75SEd Tanous {
24890fda0f12SGeorge Liu     BMCWEB_ROUTE(
24900fda0f12SGeorge Liu         app,
249122d268cbSEd Tanous         "/redfish/v1/Systems/<str>/LogServices/Crashdump/Actions/LogService.CollectDiagnosticData/")
249250d9f38aSMyung Bae         .privileges(redfish::privileges::
249350d9f38aSMyung Bae                         postLogServiceSubOverComputerSystemLogServiceCollection)
2494002d39b4SEd Tanous         .methods(boost::beast::http::verb::post)(
2495002d39b4SEd Tanous             [&app](const crow::Request& req,
249622d268cbSEd Tanous                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
249722d268cbSEd Tanous                    const std::string& systemName) {
24983ba00073SCarson Labrado                 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
249945ca1b86SEd Tanous                 {
250045ca1b86SEd Tanous                     return;
250145ca1b86SEd Tanous                 }
250222d268cbSEd Tanous 
250325b54dbaSEd Tanous                 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
25047f3e84a1SEd Tanous                 {
25057f3e84a1SEd Tanous                     // Option currently returns no systems.  TBD
25067f3e84a1SEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
25077f3e84a1SEd Tanous                                                systemName);
25087f3e84a1SEd Tanous                     return;
25097f3e84a1SEd Tanous                 }
2510253f11b8SEd Tanous                 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
251122d268cbSEd Tanous                 {
251222d268cbSEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
251322d268cbSEd Tanous                                                systemName);
251422d268cbSEd Tanous                     return;
251522d268cbSEd Tanous                 }
251622d268cbSEd Tanous 
25178e6c099aSJason M. Bills                 std::string diagnosticDataType;
25188e6c099aSJason M. Bills                 std::string oemDiagnosticDataType;
2519afc474aeSMyung Bae                 if (!redfish::json_util::readJsonAction(               //
2520afc474aeSMyung Bae                         req, asyncResp->res,                           //
2521afc474aeSMyung Bae                         "DiagnosticDataType", diagnosticDataType,      //
2522afc474aeSMyung Bae                         "OEMDiagnosticDataType", oemDiagnosticDataType //
2523afc474aeSMyung Bae                         ))
25248e6c099aSJason M. Bills                 {
25258e6c099aSJason M. Bills                     return;
25268e6c099aSJason M. Bills                 }
25278e6c099aSJason M. Bills 
25288e6c099aSJason M. Bills                 if (diagnosticDataType != "OEM")
25298e6c099aSJason M. Bills                 {
253062598e31SEd Tanous                     BMCWEB_LOG_ERROR(
253162598e31SEd Tanous                         "Only OEM DiagnosticDataType supported for Crashdump");
25328e6c099aSJason M. Bills                     messages::actionParameterValueFormatError(
2533bd79bce8SPatrick Williams                         asyncResp->res, diagnosticDataType,
2534bd79bce8SPatrick Williams                         "DiagnosticDataType", "CollectDiagnosticData");
25358e6c099aSJason M. Bills                     return;
25368e6c099aSJason M. Bills                 }
25378e6c099aSJason M. Bills 
2538c5a4c82aSJason M. Bills                 OEMDiagnosticType oemDiagType =
2539c5a4c82aSJason M. Bills                     getOEMDiagnosticType(oemDiagnosticDataType);
2540c5a4c82aSJason M. Bills 
2541c5a4c82aSJason M. Bills                 std::string iface;
2542c5a4c82aSJason M. Bills                 std::string method;
2543c5a4c82aSJason M. Bills                 std::string taskMatchStr;
2544c5a4c82aSJason M. Bills                 if (oemDiagType == OEMDiagnosticType::onDemand)
2545c5a4c82aSJason M. Bills                 {
2546c5a4c82aSJason M. Bills                     iface = crashdumpOnDemandInterface;
2547c5a4c82aSJason M. Bills                     method = "GenerateOnDemandLog";
2548bd79bce8SPatrick Williams                     taskMatchStr =
2549bd79bce8SPatrick Williams                         "type='signal',"
2550c5a4c82aSJason M. Bills                         "interface='org.freedesktop.DBus.Properties',"
2551c5a4c82aSJason M. Bills                         "member='PropertiesChanged',"
2552c5a4c82aSJason M. Bills                         "arg0namespace='com.intel.crashdump'";
2553c5a4c82aSJason M. Bills                 }
2554c5a4c82aSJason M. Bills                 else if (oemDiagType == OEMDiagnosticType::telemetry)
2555c5a4c82aSJason M. Bills                 {
2556c5a4c82aSJason M. Bills                     iface = crashdumpTelemetryInterface;
2557c5a4c82aSJason M. Bills                     method = "GenerateTelemetryLog";
2558bd79bce8SPatrick Williams                     taskMatchStr =
2559bd79bce8SPatrick Williams                         "type='signal',"
2560c5a4c82aSJason M. Bills                         "interface='org.freedesktop.DBus.Properties',"
2561c5a4c82aSJason M. Bills                         "member='PropertiesChanged',"
2562c5a4c82aSJason M. Bills                         "arg0namespace='com.intel.crashdump'";
2563c5a4c82aSJason M. Bills                 }
2564c5a4c82aSJason M. Bills                 else
2565c5a4c82aSJason M. Bills                 {
256662598e31SEd Tanous                     BMCWEB_LOG_ERROR("Unsupported OEMDiagnosticDataType: {}",
256762598e31SEd Tanous                                      oemDiagnosticDataType);
2568c5a4c82aSJason M. Bills                     messages::actionParameterValueFormatError(
2569bd79bce8SPatrick Williams                         asyncResp->res, oemDiagnosticDataType,
2570bd79bce8SPatrick Williams                         "OEMDiagnosticDataType", "CollectDiagnosticData");
2571c5a4c82aSJason M. Bills                     return;
2572c5a4c82aSJason M. Bills                 }
2573c5a4c82aSJason M. Bills 
2574c5a4c82aSJason M. Bills                 auto collectCrashdumpCallback =
2575c5a4c82aSJason M. Bills                     [asyncResp, payload(task::Payload(req)),
25765e7e2dc5SEd Tanous                      taskMatchStr](const boost::system::error_code& ec,
257798be3e39SEd Tanous                                    const std::string&) mutable {
25781da66f75SEd Tanous                         if (ec)
25791da66f75SEd Tanous                         {
2580bd79bce8SPatrick Williams                             if (ec.value() ==
2581bd79bce8SPatrick Williams                                 boost::system::errc::operation_not_supported)
25821da66f75SEd Tanous                             {
2583f12894f8SJason M. Bills                                 messages::resourceInStandby(asyncResp->res);
25841da66f75SEd Tanous                             }
2585bd79bce8SPatrick Williams                             else if (ec.value() == boost::system::errc::
2586bd79bce8SPatrick Williams                                                        device_or_resource_busy)
25874363d3b2SJason M. Bills                             {
2588bd79bce8SPatrick Williams                                 messages::serviceTemporarilyUnavailable(
2589bd79bce8SPatrick Williams                                     asyncResp->res, "60");
25904363d3b2SJason M. Bills                             }
25911da66f75SEd Tanous                             else
25921da66f75SEd Tanous                             {
2593f12894f8SJason M. Bills                                 messages::internalError(asyncResp->res);
25941da66f75SEd Tanous                             }
25951da66f75SEd Tanous                             return;
25961da66f75SEd Tanous                         }
2597bd79bce8SPatrick Williams                         std::shared_ptr<task::TaskData> task =
2598bd79bce8SPatrick Williams                             task::TaskData::createTask(
2599bd79bce8SPatrick Williams                                 [](const boost::system::error_code& ec2,
2600bd79bce8SPatrick Williams                                    sdbusplus::message_t&,
2601bd79bce8SPatrick Williams                                    const std::shared_ptr<task::TaskData>&
2602bd79bce8SPatrick Williams                                        taskData) {
26038b24275dSEd Tanous                                     if (!ec2)
260466afe4faSJames Feist                                     {
2605bd79bce8SPatrick Williams                                         taskData->messages.emplace_back(
2606bd79bce8SPatrick Williams                                             messages::taskCompletedOK(
2607bd79bce8SPatrick Williams                                                 std::to_string(
2608bd79bce8SPatrick Williams                                                     taskData->index)));
2609831d6b09SJames Feist                                         taskData->state = "Completed";
261066afe4faSJames Feist                                     }
261132898ceaSJames Feist                                     return task::completed;
261266afe4faSJames Feist                                 },
2613c5a4c82aSJason M. Bills                                 taskMatchStr);
2614c5a4c82aSJason M. Bills 
261546229577SJames Feist                         task->startTimer(std::chrono::minutes(5));
261698be3e39SEd Tanous                         task->payload.emplace(std::move(payload));
261729e2bdd7SChinmay Shripad Hegde                         task->populateResp(asyncResp->res);
26181da66f75SEd Tanous                     };
26198e6c099aSJason M. Bills 
2620177612aaSEd Tanous                 dbus::utility::async_method_call(
2621177612aaSEd Tanous                     asyncResp, std::move(collectCrashdumpCallback),
2622177612aaSEd Tanous                     crashdumpObject, crashdumpPath, iface, method);
26237e860f15SJohn Edward Broadbent             });
26246eda7685SKenny L. Ku }
26256eda7685SKenny L. Ku 
2626599b9af3SAlexander Hansen inline void dBusLogServiceActionsClear(
2627599b9af3SAlexander Hansen     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2628599b9af3SAlexander Hansen {
2629599b9af3SAlexander Hansen     BMCWEB_LOG_DEBUG("Do delete all entries.");
2630599b9af3SAlexander Hansen 
2631599b9af3SAlexander Hansen     // Process response from Logging service.
2632599b9af3SAlexander Hansen     auto respHandler = [asyncResp](const boost::system::error_code& ec) {
2633599b9af3SAlexander Hansen         BMCWEB_LOG_DEBUG("doClearLog resp_handler callback: Done");
2634599b9af3SAlexander Hansen         if (ec)
2635599b9af3SAlexander Hansen         {
2636599b9af3SAlexander Hansen             // TODO Handle for specific error code
2637599b9af3SAlexander Hansen             BMCWEB_LOG_ERROR("doClearLog resp_handler got error {}", ec);
2638599b9af3SAlexander Hansen             asyncResp->res.result(
2639599b9af3SAlexander Hansen                 boost::beast::http::status::internal_server_error);
2640599b9af3SAlexander Hansen             return;
2641599b9af3SAlexander Hansen         }
2642599b9af3SAlexander Hansen 
2643e2460466SAmy Chang         messages::success(asyncResp->res);
2644599b9af3SAlexander Hansen     };
2645599b9af3SAlexander Hansen 
2646599b9af3SAlexander Hansen     // Make call to Logging service to request Clear Log
2647177612aaSEd Tanous     dbus::utility::async_method_call(
2648177612aaSEd Tanous         asyncResp, respHandler, "xyz.openbmc_project.Logging",
2649599b9af3SAlexander Hansen         "/xyz/openbmc_project/logging",
2650599b9af3SAlexander Hansen         "xyz.openbmc_project.Collection.DeleteAll", "DeleteAll");
2651599b9af3SAlexander Hansen }
2652599b9af3SAlexander Hansen 
2653cb92c03bSAndrew Geissler /**
2654cb92c03bSAndrew Geissler  * DBusLogServiceActionsClear class supports POST method for ClearLog action.
2655cb92c03bSAndrew Geissler  */
26567e860f15SJohn Edward Broadbent inline void requestRoutesDBusLogServiceActionsClear(App& app)
2657cb92c03bSAndrew Geissler {
2658cb92c03bSAndrew Geissler     /**
2659cb92c03bSAndrew Geissler      * Function handles POST method request.
2660cb92c03bSAndrew Geissler      * The Clear Log actions does not require any parameter.The action deletes
2661cb92c03bSAndrew Geissler      * all entries found in the Entries collection for this Log Service.
2662cb92c03bSAndrew Geissler      */
26637e860f15SJohn Edward Broadbent 
26640fda0f12SGeorge Liu     BMCWEB_ROUTE(
26650fda0f12SGeorge Liu         app,
266622d268cbSEd Tanous         "/redfish/v1/Systems/<str>/LogServices/EventLog/Actions/LogService.ClearLog/")
2667fff6a4d3SAbhishek Patel         .privileges(redfish::privileges::
2668fff6a4d3SAbhishek Patel                         postLogServiceSubOverComputerSystemLogServiceCollection)
26697e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::post)(
267045ca1b86SEd Tanous             [&app](const crow::Request& req,
267122d268cbSEd Tanous                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
267222d268cbSEd Tanous                    const std::string& systemName) {
26733ba00073SCarson Labrado                 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
267445ca1b86SEd Tanous                 {
267545ca1b86SEd Tanous                     return;
267645ca1b86SEd Tanous                 }
267725b54dbaSEd Tanous                 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
26787f3e84a1SEd Tanous                 {
26797f3e84a1SEd Tanous                     // Option currently returns no systems.  TBD
26807f3e84a1SEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
26817f3e84a1SEd Tanous                                                systemName);
26827f3e84a1SEd Tanous                     return;
26837f3e84a1SEd Tanous                 }
2684253f11b8SEd Tanous                 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
268522d268cbSEd Tanous                 {
268622d268cbSEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
268722d268cbSEd Tanous                                                systemName);
268822d268cbSEd Tanous                     return;
268922d268cbSEd Tanous                 }
2690599b9af3SAlexander Hansen                 dBusLogServiceActionsClear(asyncResp);
26917e860f15SJohn Edward Broadbent             });
2692cb92c03bSAndrew Geissler }
2693a3316fc6SZhikuiRen 
26941da66f75SEd Tanous } // namespace redfish
2695