xref: /openbmc/bmcweb/features/redfish/lib/log_services.hpp (revision 664c95605d55d04c03a7fb40de1d0b22ce1be946)
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"
18b7028ebfSSpencer Ku #include "human_sort.hpp"
19d7857201SEd Tanous #include "logging.hpp"
203ccb3adbSEd Tanous #include "query.hpp"
213ccb3adbSEd Tanous #include "registries/privilege_registry.hpp"
22d7857201SEd Tanous #include "str_utility.hpp"
2346229577SJames Feist #include "task.hpp"
245b90429aSEd Tanous #include "task_messages.hpp"
253ccb3adbSEd Tanous #include "utils/dbus_utils.hpp"
26*08fad5d9SCorey Ethington #include "utils/etag_utils.hpp"
275b90429aSEd Tanous #include "utils/json_utils.hpp"
28ff35df94SOliver Brewka #include "utils/log_services_utils.hpp"
293ccb3adbSEd Tanous #include "utils/time_utils.hpp"
301da66f75SEd Tanous 
31d7857201SEd Tanous #include <asm-generic/errno.h>
32d7857201SEd Tanous #include <systemd/sd-bus.h>
338e31778eSAsmitha Karunanithi #include <tinyxml2.h>
34400fd1fbSAdriana Kobylak #include <unistd.h>
35e1f26343SJason M. Bills 
36d7857201SEd Tanous #include <boost/beast/http/field.hpp>
37d7857201SEd Tanous #include <boost/beast/http/status.hpp>
3807c8c20dSEd Tanous #include <boost/beast/http/verb.hpp>
391ddcf01aSJason M. Bills #include <boost/system/linux_error.hpp>
40ef4c65b7SEd Tanous #include <boost/url/format.hpp>
41d7857201SEd Tanous #include <boost/url/url.hpp>
42d7857201SEd Tanous #include <sdbusplus/message.hpp>
43d7857201SEd Tanous #include <sdbusplus/message/native_types.hpp>
44d1bde9e5SKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp>
451214b7e7SGunnar Mills 
46d7857201SEd Tanous #include <algorithm>
477a1dbc48SGeorge Liu #include <array>
48d7857201SEd Tanous #include <chrono>
49d7857201SEd Tanous #include <cstdint>
504418c7f0SJames Feist #include <filesystem>
51d7857201SEd Tanous #include <format>
52d7857201SEd Tanous #include <functional>
5318f8f608SEd Tanous #include <iterator>
54d7857201SEd Tanous #include <memory>
5575710de2SXiaochao Ma #include <optional>
563544d2a7SEd Tanous #include <ranges>
5726702d01SEd Tanous #include <span>
5818f8f608SEd Tanous #include <string>
59cd225da8SJason M. Bills #include <string_view>
60d7857201SEd Tanous #include <utility>
61abf2add6SEd Tanous #include <variant>
62d7857201SEd Tanous #include <vector>
631da66f75SEd Tanous 
641da66f75SEd Tanous namespace redfish
651da66f75SEd Tanous {
661da66f75SEd Tanous 
6789492a15SPatrick Williams constexpr const char* crashdumpObject = "com.intel.crashdump";
6889492a15SPatrick Williams constexpr const char* crashdumpPath = "/com/intel/crashdump";
6989492a15SPatrick Williams constexpr const char* crashdumpInterface = "com.intel.crashdump";
7089492a15SPatrick Williams constexpr const char* deleteAllInterface =
715b61b5e8SJason M. Bills     "xyz.openbmc_project.Collection.DeleteAll";
7289492a15SPatrick Williams constexpr const char* crashdumpOnDemandInterface =
73424c4176SJason M. Bills     "com.intel.crashdump.OnDemand";
7489492a15SPatrick Williams constexpr const char* crashdumpTelemetryInterface =
756eda7685SKenny L. Ku     "com.intel.crashdump.Telemetry";
761da66f75SEd Tanous 
778e31778eSAsmitha Karunanithi enum class DumpCreationProgress
788e31778eSAsmitha Karunanithi {
798e31778eSAsmitha Karunanithi     DUMP_CREATE_SUCCESS,
808e31778eSAsmitha Karunanithi     DUMP_CREATE_FAILED,
818e31778eSAsmitha Karunanithi     DUMP_CREATE_INPROGRESS
828e31778eSAsmitha Karunanithi };
838e31778eSAsmitha Karunanithi 
8418f8f608SEd Tanous inline std::string getDumpPath(std::string_view dumpType)
8518f8f608SEd Tanous {
8618f8f608SEd Tanous     std::string dbusDumpPath = "/xyz/openbmc_project/dump/";
8718f8f608SEd Tanous     std::ranges::transform(dumpType, std::back_inserter(dbusDumpPath),
8818f8f608SEd Tanous                            bmcweb::asciiToLower);
8918f8f608SEd Tanous 
9018f8f608SEd Tanous     return dbusDumpPath;
9118f8f608SEd Tanous }
9218f8f608SEd Tanous 
93504af5a0SPatrick Williams inline log_entry::OriginatorTypes mapDbusOriginatorTypeToRedfish(
94504af5a0SPatrick Williams     const std::string& originatorType)
9568dd075aSAsmitha Karunanithi {
9668dd075aSAsmitha Karunanithi     if (originatorType ==
9768dd075aSAsmitha Karunanithi         "xyz.openbmc_project.Common.OriginatedBy.OriginatorTypes.Client")
9868dd075aSAsmitha Karunanithi     {
9968dd075aSAsmitha Karunanithi         return log_entry::OriginatorTypes::Client;
10068dd075aSAsmitha Karunanithi     }
10168dd075aSAsmitha Karunanithi     if (originatorType ==
10268dd075aSAsmitha Karunanithi         "xyz.openbmc_project.Common.OriginatedBy.OriginatorTypes.Internal")
10368dd075aSAsmitha Karunanithi     {
10468dd075aSAsmitha Karunanithi         return log_entry::OriginatorTypes::Internal;
10568dd075aSAsmitha Karunanithi     }
10668dd075aSAsmitha Karunanithi     if (originatorType ==
10768dd075aSAsmitha Karunanithi         "xyz.openbmc_project.Common.OriginatedBy.OriginatorTypes.SupportingService")
10868dd075aSAsmitha Karunanithi     {
10968dd075aSAsmitha Karunanithi         return log_entry::OriginatorTypes::SupportingService;
11068dd075aSAsmitha Karunanithi     }
11168dd075aSAsmitha Karunanithi     return log_entry::OriginatorTypes::Invalid;
11268dd075aSAsmitha Karunanithi }
11368dd075aSAsmitha Karunanithi 
114aefe3786SClaire Weinan inline void parseDumpEntryFromDbusObject(
1152d613eb6SJiaqing Zhao     const dbus::utility::ManagedObjectType::value_type& object,
116c6fecdabSClaire Weinan     std::string& dumpStatus, uint64_t& size, uint64_t& timestampUs,
11768dd075aSAsmitha Karunanithi     std::string& originatorId, log_entry::OriginatorTypes& originatorType,
118aefe3786SClaire Weinan     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
119aefe3786SClaire Weinan {
120aefe3786SClaire Weinan     for (const auto& interfaceMap : object.second)
121aefe3786SClaire Weinan     {
122aefe3786SClaire Weinan         if (interfaceMap.first == "xyz.openbmc_project.Common.Progress")
123aefe3786SClaire Weinan         {
124aefe3786SClaire Weinan             for (const auto& propertyMap : interfaceMap.second)
125aefe3786SClaire Weinan             {
126aefe3786SClaire Weinan                 if (propertyMap.first == "Status")
127aefe3786SClaire Weinan                 {
128aefe3786SClaire Weinan                     const auto* status =
129aefe3786SClaire Weinan                         std::get_if<std::string>(&propertyMap.second);
130aefe3786SClaire Weinan                     if (status == nullptr)
131aefe3786SClaire Weinan                     {
132aefe3786SClaire Weinan                         messages::internalError(asyncResp->res);
133aefe3786SClaire Weinan                         break;
134aefe3786SClaire Weinan                     }
135aefe3786SClaire Weinan                     dumpStatus = *status;
136aefe3786SClaire Weinan                 }
137aefe3786SClaire Weinan             }
138aefe3786SClaire Weinan         }
139aefe3786SClaire Weinan         else if (interfaceMap.first == "xyz.openbmc_project.Dump.Entry")
140aefe3786SClaire Weinan         {
141aefe3786SClaire Weinan             for (const auto& propertyMap : interfaceMap.second)
142aefe3786SClaire Weinan             {
143aefe3786SClaire Weinan                 if (propertyMap.first == "Size")
144aefe3786SClaire Weinan                 {
145aefe3786SClaire Weinan                     const auto* sizePtr =
146aefe3786SClaire Weinan                         std::get_if<uint64_t>(&propertyMap.second);
147aefe3786SClaire Weinan                     if (sizePtr == nullptr)
148aefe3786SClaire Weinan                     {
149aefe3786SClaire Weinan                         messages::internalError(asyncResp->res);
150aefe3786SClaire Weinan                         break;
151aefe3786SClaire Weinan                     }
152aefe3786SClaire Weinan                     size = *sizePtr;
153aefe3786SClaire Weinan                     break;
154aefe3786SClaire Weinan                 }
155aefe3786SClaire Weinan             }
156aefe3786SClaire Weinan         }
157aefe3786SClaire Weinan         else if (interfaceMap.first == "xyz.openbmc_project.Time.EpochTime")
158aefe3786SClaire Weinan         {
159aefe3786SClaire Weinan             for (const auto& propertyMap : interfaceMap.second)
160aefe3786SClaire Weinan             {
161aefe3786SClaire Weinan                 if (propertyMap.first == "Elapsed")
162aefe3786SClaire Weinan                 {
163aefe3786SClaire Weinan                     const uint64_t* usecsTimeStamp =
164aefe3786SClaire Weinan                         std::get_if<uint64_t>(&propertyMap.second);
165aefe3786SClaire Weinan                     if (usecsTimeStamp == nullptr)
166aefe3786SClaire Weinan                     {
167aefe3786SClaire Weinan                         messages::internalError(asyncResp->res);
168aefe3786SClaire Weinan                         break;
169aefe3786SClaire Weinan                     }
170c6fecdabSClaire Weinan                     timestampUs = *usecsTimeStamp;
171aefe3786SClaire Weinan                     break;
172aefe3786SClaire Weinan                 }
173aefe3786SClaire Weinan             }
174aefe3786SClaire Weinan         }
17568dd075aSAsmitha Karunanithi         else if (interfaceMap.first ==
17668dd075aSAsmitha Karunanithi                  "xyz.openbmc_project.Common.OriginatedBy")
17768dd075aSAsmitha Karunanithi         {
17868dd075aSAsmitha Karunanithi             for (const auto& propertyMap : interfaceMap.second)
17968dd075aSAsmitha Karunanithi             {
18068dd075aSAsmitha Karunanithi                 if (propertyMap.first == "OriginatorId")
18168dd075aSAsmitha Karunanithi                 {
18268dd075aSAsmitha Karunanithi                     const std::string* id =
18368dd075aSAsmitha Karunanithi                         std::get_if<std::string>(&propertyMap.second);
18468dd075aSAsmitha Karunanithi                     if (id == nullptr)
18568dd075aSAsmitha Karunanithi                     {
18668dd075aSAsmitha Karunanithi                         messages::internalError(asyncResp->res);
18768dd075aSAsmitha Karunanithi                         break;
18868dd075aSAsmitha Karunanithi                     }
18968dd075aSAsmitha Karunanithi                     originatorId = *id;
19068dd075aSAsmitha Karunanithi                 }
19168dd075aSAsmitha Karunanithi 
19268dd075aSAsmitha Karunanithi                 if (propertyMap.first == "OriginatorType")
19368dd075aSAsmitha Karunanithi                 {
19468dd075aSAsmitha Karunanithi                     const std::string* type =
19568dd075aSAsmitha Karunanithi                         std::get_if<std::string>(&propertyMap.second);
19668dd075aSAsmitha Karunanithi                     if (type == nullptr)
19768dd075aSAsmitha Karunanithi                     {
19868dd075aSAsmitha Karunanithi                         messages::internalError(asyncResp->res);
19968dd075aSAsmitha Karunanithi                         break;
20068dd075aSAsmitha Karunanithi                     }
20168dd075aSAsmitha Karunanithi 
20268dd075aSAsmitha Karunanithi                     originatorType = mapDbusOriginatorTypeToRedfish(*type);
20368dd075aSAsmitha Karunanithi                     if (originatorType == log_entry::OriginatorTypes::Invalid)
20468dd075aSAsmitha Karunanithi                     {
20568dd075aSAsmitha Karunanithi                         messages::internalError(asyncResp->res);
20668dd075aSAsmitha Karunanithi                         break;
20768dd075aSAsmitha Karunanithi                     }
20868dd075aSAsmitha Karunanithi                 }
20968dd075aSAsmitha Karunanithi             }
21068dd075aSAsmitha Karunanithi         }
211aefe3786SClaire Weinan     }
212aefe3786SClaire Weinan }
213aefe3786SClaire Weinan 
21421ab404cSNan Zhou static std::string getDumpEntriesPath(const std::string& dumpType)
215fdd26906SClaire Weinan {
216fdd26906SClaire Weinan     std::string entriesPath;
217fdd26906SClaire Weinan 
218fdd26906SClaire Weinan     if (dumpType == "BMC")
219fdd26906SClaire Weinan     {
220253f11b8SEd Tanous         entriesPath =
221253f11b8SEd Tanous             std::format("/redfish/v1/Managers/{}/LogServices/Dump/Entries/",
222253f11b8SEd Tanous                         BMCWEB_REDFISH_MANAGER_URI_NAME);
223fdd26906SClaire Weinan     }
224fdd26906SClaire Weinan     else if (dumpType == "FaultLog")
225fdd26906SClaire Weinan     {
226253f11b8SEd Tanous         entriesPath =
227253f11b8SEd Tanous             std::format("/redfish/v1/Managers/{}/LogServices/FaultLog/Entries/",
228253f11b8SEd Tanous                         BMCWEB_REDFISH_MANAGER_URI_NAME);
229fdd26906SClaire Weinan     }
230fdd26906SClaire Weinan     else if (dumpType == "System")
231fdd26906SClaire Weinan     {
232253f11b8SEd Tanous         entriesPath =
233253f11b8SEd Tanous             std::format("/redfish/v1/Systems/{}/LogServices/Dump/Entries/",
234253f11b8SEd Tanous                         BMCWEB_REDFISH_SYSTEM_URI_NAME);
235fdd26906SClaire Weinan     }
236fdd26906SClaire Weinan     else
237fdd26906SClaire Weinan     {
23862598e31SEd Tanous         BMCWEB_LOG_ERROR("getDumpEntriesPath() invalid dump type: {}",
23962598e31SEd Tanous                          dumpType);
240fdd26906SClaire Weinan     }
241fdd26906SClaire Weinan 
242fdd26906SClaire Weinan     // Returns empty string on error
243fdd26906SClaire Weinan     return entriesPath;
244fdd26906SClaire Weinan }
245fdd26906SClaire Weinan 
246504af5a0SPatrick Williams inline void getDumpEntryCollection(
247504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2485cb1dd27SAsmitha Karunanithi     const std::string& dumpType)
2495cb1dd27SAsmitha Karunanithi {
250fdd26906SClaire Weinan     std::string entriesPath = getDumpEntriesPath(dumpType);
251fdd26906SClaire Weinan     if (entriesPath.empty())
2525cb1dd27SAsmitha Karunanithi     {
2535cb1dd27SAsmitha Karunanithi         messages::internalError(asyncResp->res);
2545cb1dd27SAsmitha Karunanithi         return;
2555cb1dd27SAsmitha Karunanithi     }
2565cb1dd27SAsmitha Karunanithi 
2575eb468daSGeorge Liu     sdbusplus::message::object_path path("/xyz/openbmc_project/dump");
2585eb468daSGeorge Liu     dbus::utility::getManagedObjects(
2595eb468daSGeorge Liu         "xyz.openbmc_project.Dump.Manager", path,
260fdd26906SClaire Weinan         [asyncResp, entriesPath,
2615e7e2dc5SEd Tanous          dumpType](const boost::system::error_code& ec,
2625eb468daSGeorge Liu                    const dbus::utility::ManagedObjectType& objects) {
2635cb1dd27SAsmitha Karunanithi             if (ec)
2645cb1dd27SAsmitha Karunanithi             {
26562598e31SEd Tanous                 BMCWEB_LOG_ERROR("DumpEntry resp_handler got error {}", ec);
2665cb1dd27SAsmitha Karunanithi                 messages::internalError(asyncResp->res);
2675cb1dd27SAsmitha Karunanithi                 return;
2685cb1dd27SAsmitha Karunanithi             }
2695cb1dd27SAsmitha Karunanithi 
270fdd26906SClaire Weinan             // Remove ending slash
271fdd26906SClaire Weinan             std::string odataIdStr = entriesPath;
272fdd26906SClaire Weinan             if (!odataIdStr.empty())
273fdd26906SClaire Weinan             {
274fdd26906SClaire Weinan                 odataIdStr.pop_back();
275fdd26906SClaire Weinan             }
276fdd26906SClaire Weinan 
277fdd26906SClaire Weinan             asyncResp->res.jsonValue["@odata.type"] =
278fdd26906SClaire Weinan                 "#LogEntryCollection.LogEntryCollection";
279fdd26906SClaire Weinan             asyncResp->res.jsonValue["@odata.id"] = std::move(odataIdStr);
280fdd26906SClaire Weinan             asyncResp->res.jsonValue["Name"] = dumpType + " Dump Entries";
281bd79bce8SPatrick Williams             asyncResp->res.jsonValue["Description"] =
282bd79bce8SPatrick Williams                 "Collection of " + dumpType + " Dump Entries";
283fdd26906SClaire Weinan 
2843544d2a7SEd Tanous             nlohmann::json::array_t entriesArray;
28518f8f608SEd Tanous             std::string dumpEntryPath = getDumpPath(dumpType) + "/entry/";
2865cb1dd27SAsmitha Karunanithi 
2875eb468daSGeorge Liu             dbus::utility::ManagedObjectType resp(objects);
2883544d2a7SEd Tanous             std::ranges::sort(resp, [](const auto& l, const auto& r) {
289002d39b4SEd Tanous                 return AlphanumLess<std::string>()(l.first.filename(),
290002d39b4SEd Tanous                                                    r.first.filename());
291565dfb6fSClaire Weinan             });
292565dfb6fSClaire Weinan 
2935cb1dd27SAsmitha Karunanithi             for (auto& object : resp)
2945cb1dd27SAsmitha Karunanithi             {
295b47452b2SAsmitha Karunanithi                 if (object.first.str.find(dumpEntryPath) == std::string::npos)
2965cb1dd27SAsmitha Karunanithi                 {
2975cb1dd27SAsmitha Karunanithi                     continue;
2985cb1dd27SAsmitha Karunanithi                 }
299c6fecdabSClaire Weinan                 uint64_t timestampUs = 0;
3005cb1dd27SAsmitha Karunanithi                 uint64_t size = 0;
30135440d18SAsmitha Karunanithi                 std::string dumpStatus;
30268dd075aSAsmitha Karunanithi                 std::string originatorId;
30368dd075aSAsmitha Karunanithi                 log_entry::OriginatorTypes originatorType =
30468dd075aSAsmitha Karunanithi                     log_entry::OriginatorTypes::Internal;
305433b68b4SJason M. Bills                 nlohmann::json::object_t thisEntry;
3062dfd18efSEd Tanous 
3072dfd18efSEd Tanous                 std::string entryID = object.first.filename();
3082dfd18efSEd Tanous                 if (entryID.empty())
3095cb1dd27SAsmitha Karunanithi                 {
3105cb1dd27SAsmitha Karunanithi                     continue;
3115cb1dd27SAsmitha Karunanithi                 }
3125cb1dd27SAsmitha Karunanithi 
313bd79bce8SPatrick Williams                 parseDumpEntryFromDbusObject(object, dumpStatus, size,
314bd79bce8SPatrick Williams                                              timestampUs, originatorId,
315bd79bce8SPatrick Williams                                              originatorType, asyncResp);
3165cb1dd27SAsmitha Karunanithi 
3170fda0f12SGeorge Liu                 if (dumpStatus !=
3180fda0f12SGeorge Liu                         "xyz.openbmc_project.Common.Progress.OperationStatus.Completed" &&
31935440d18SAsmitha Karunanithi                     !dumpStatus.empty())
32035440d18SAsmitha Karunanithi                 {
32135440d18SAsmitha Karunanithi                     // Dump status is not Complete, no need to enumerate
32235440d18SAsmitha Karunanithi                     continue;
32335440d18SAsmitha Karunanithi                 }
32435440d18SAsmitha Karunanithi 
32568dd075aSAsmitha Karunanithi                 thisEntry["@odata.type"] = "#LogEntry.v1_11_0.LogEntry";
326fdd26906SClaire Weinan                 thisEntry["@odata.id"] = entriesPath + entryID;
3275cb1dd27SAsmitha Karunanithi                 thisEntry["Id"] = entryID;
3285cb1dd27SAsmitha Karunanithi                 thisEntry["EntryType"] = "Event";
3295cb1dd27SAsmitha Karunanithi                 thisEntry["Name"] = dumpType + " Dump Entry";
330bbd80db8SClaire Weinan                 thisEntry["Created"] =
331bbd80db8SClaire Weinan                     redfish::time_utils::getDateTimeUintUs(timestampUs);
3325cb1dd27SAsmitha Karunanithi 
33368dd075aSAsmitha Karunanithi                 if (!originatorId.empty())
33468dd075aSAsmitha Karunanithi                 {
33568dd075aSAsmitha Karunanithi                     thisEntry["Originator"] = originatorId;
33668dd075aSAsmitha Karunanithi                     thisEntry["OriginatorType"] = originatorType;
33768dd075aSAsmitha Karunanithi                 }
33868dd075aSAsmitha Karunanithi 
3395cb1dd27SAsmitha Karunanithi                 if (dumpType == "BMC")
3405cb1dd27SAsmitha Karunanithi                 {
341d337bb72SAsmitha Karunanithi                     thisEntry["DiagnosticDataType"] = "Manager";
342bd79bce8SPatrick Williams                     thisEntry["AdditionalDataURI"] =
343bd79bce8SPatrick Williams                         entriesPath + entryID + "/attachment";
344fdd26906SClaire Weinan                     thisEntry["AdditionalDataSizeBytes"] = size;
3455cb1dd27SAsmitha Karunanithi                 }
3465cb1dd27SAsmitha Karunanithi                 else if (dumpType == "System")
3475cb1dd27SAsmitha Karunanithi                 {
348d337bb72SAsmitha Karunanithi                     thisEntry["DiagnosticDataType"] = "OEM";
349d337bb72SAsmitha Karunanithi                     thisEntry["OEMDiagnosticDataType"] = "System";
350bd79bce8SPatrick Williams                     thisEntry["AdditionalDataURI"] =
351bd79bce8SPatrick Williams                         entriesPath + entryID + "/attachment";
352fdd26906SClaire Weinan                     thisEntry["AdditionalDataSizeBytes"] = size;
3535cb1dd27SAsmitha Karunanithi                 }
354b2ba3072SPatrick Williams                 entriesArray.emplace_back(std::move(thisEntry));
3555cb1dd27SAsmitha Karunanithi             }
356bd79bce8SPatrick Williams             asyncResp->res.jsonValue["Members@odata.count"] =
357bd79bce8SPatrick Williams                 entriesArray.size();
3583544d2a7SEd Tanous             asyncResp->res.jsonValue["Members"] = std::move(entriesArray);
3595eb468daSGeorge Liu         });
3605cb1dd27SAsmitha Karunanithi }
3615cb1dd27SAsmitha Karunanithi 
362504af5a0SPatrick Williams inline void getDumpEntryById(
363504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3648d1b46d7Szhanghch05     const std::string& entryID, const std::string& dumpType)
3655cb1dd27SAsmitha Karunanithi {
366fdd26906SClaire Weinan     std::string entriesPath = getDumpEntriesPath(dumpType);
367fdd26906SClaire Weinan     if (entriesPath.empty())
3685cb1dd27SAsmitha Karunanithi     {
3695cb1dd27SAsmitha Karunanithi         messages::internalError(asyncResp->res);
3705cb1dd27SAsmitha Karunanithi         return;
3715cb1dd27SAsmitha Karunanithi     }
3725cb1dd27SAsmitha Karunanithi 
3735eb468daSGeorge Liu     sdbusplus::message::object_path path("/xyz/openbmc_project/dump");
3745eb468daSGeorge Liu     dbus::utility::getManagedObjects(
3755eb468daSGeorge Liu         "xyz.openbmc_project.Dump.Manager", path,
376fdd26906SClaire Weinan         [asyncResp, entryID, dumpType,
3775e7e2dc5SEd Tanous          entriesPath](const boost::system::error_code& ec,
37802cad96eSEd Tanous                       const dbus::utility::ManagedObjectType& resp) {
3795cb1dd27SAsmitha Karunanithi             if (ec)
3805cb1dd27SAsmitha Karunanithi             {
38162598e31SEd Tanous                 BMCWEB_LOG_ERROR("DumpEntry resp_handler got error {}", ec);
3825cb1dd27SAsmitha Karunanithi                 messages::internalError(asyncResp->res);
3835cb1dd27SAsmitha Karunanithi                 return;
3845cb1dd27SAsmitha Karunanithi             }
3855cb1dd27SAsmitha Karunanithi 
386b47452b2SAsmitha Karunanithi             bool foundDumpEntry = false;
38718f8f608SEd Tanous             std::string dumpEntryPath = getDumpPath(dumpType) + "/entry/";
388b47452b2SAsmitha Karunanithi 
3899eb808c1SEd Tanous             for (const auto& objectPath : resp)
3905cb1dd27SAsmitha Karunanithi             {
391b47452b2SAsmitha Karunanithi                 if (objectPath.first.str != dumpEntryPath + entryID)
3925cb1dd27SAsmitha Karunanithi                 {
3935cb1dd27SAsmitha Karunanithi                     continue;
3945cb1dd27SAsmitha Karunanithi                 }
3955cb1dd27SAsmitha Karunanithi 
3965cb1dd27SAsmitha Karunanithi                 foundDumpEntry = true;
397c6fecdabSClaire Weinan                 uint64_t timestampUs = 0;
3985cb1dd27SAsmitha Karunanithi                 uint64_t size = 0;
39935440d18SAsmitha Karunanithi                 std::string dumpStatus;
40068dd075aSAsmitha Karunanithi                 std::string originatorId;
40168dd075aSAsmitha Karunanithi                 log_entry::OriginatorTypes originatorType =
40268dd075aSAsmitha Karunanithi                     log_entry::OriginatorTypes::Internal;
4035cb1dd27SAsmitha Karunanithi 
404aefe3786SClaire Weinan                 parseDumpEntryFromDbusObject(objectPath, dumpStatus, size,
40568dd075aSAsmitha Karunanithi                                              timestampUs, originatorId,
40668dd075aSAsmitha Karunanithi                                              originatorType, asyncResp);
4075cb1dd27SAsmitha Karunanithi 
4080fda0f12SGeorge Liu                 if (dumpStatus !=
4090fda0f12SGeorge Liu                         "xyz.openbmc_project.Common.Progress.OperationStatus.Completed" &&
41035440d18SAsmitha Karunanithi                     !dumpStatus.empty())
41135440d18SAsmitha Karunanithi                 {
41235440d18SAsmitha Karunanithi                     // Dump status is not Complete
41335440d18SAsmitha Karunanithi                     // return not found until status is changed to Completed
414bd79bce8SPatrick Williams                     messages::resourceNotFound(asyncResp->res,
415bd79bce8SPatrick Williams                                                dumpType + " dump", entryID);
41635440d18SAsmitha Karunanithi                     return;
41735440d18SAsmitha Karunanithi                 }
41835440d18SAsmitha Karunanithi 
4195cb1dd27SAsmitha Karunanithi                 asyncResp->res.jsonValue["@odata.type"] =
42068dd075aSAsmitha Karunanithi                     "#LogEntry.v1_11_0.LogEntry";
421fdd26906SClaire Weinan                 asyncResp->res.jsonValue["@odata.id"] = entriesPath + entryID;
4225cb1dd27SAsmitha Karunanithi                 asyncResp->res.jsonValue["Id"] = entryID;
4235cb1dd27SAsmitha Karunanithi                 asyncResp->res.jsonValue["EntryType"] = "Event";
4245cb1dd27SAsmitha Karunanithi                 asyncResp->res.jsonValue["Name"] = dumpType + " Dump Entry";
425bbd80db8SClaire Weinan                 asyncResp->res.jsonValue["Created"] =
426bbd80db8SClaire Weinan                     redfish::time_utils::getDateTimeUintUs(timestampUs);
4275cb1dd27SAsmitha Karunanithi 
42868dd075aSAsmitha Karunanithi                 if (!originatorId.empty())
42968dd075aSAsmitha Karunanithi                 {
43068dd075aSAsmitha Karunanithi                     asyncResp->res.jsonValue["Originator"] = originatorId;
43168dd075aSAsmitha Karunanithi                     asyncResp->res.jsonValue["OriginatorType"] = originatorType;
43268dd075aSAsmitha Karunanithi                 }
43368dd075aSAsmitha Karunanithi 
4345cb1dd27SAsmitha Karunanithi                 if (dumpType == "BMC")
4355cb1dd27SAsmitha Karunanithi                 {
436d337bb72SAsmitha Karunanithi                     asyncResp->res.jsonValue["DiagnosticDataType"] = "Manager";
437d337bb72SAsmitha Karunanithi                     asyncResp->res.jsonValue["AdditionalDataURI"] =
438fdd26906SClaire Weinan                         entriesPath + entryID + "/attachment";
439fdd26906SClaire Weinan                     asyncResp->res.jsonValue["AdditionalDataSizeBytes"] = size;
4405cb1dd27SAsmitha Karunanithi                 }
4415cb1dd27SAsmitha Karunanithi                 else if (dumpType == "System")
4425cb1dd27SAsmitha Karunanithi                 {
443d337bb72SAsmitha Karunanithi                     asyncResp->res.jsonValue["DiagnosticDataType"] = "OEM";
444bd79bce8SPatrick Williams                     asyncResp->res.jsonValue["OEMDiagnosticDataType"] =
445bd79bce8SPatrick Williams                         "System";
446d337bb72SAsmitha Karunanithi                     asyncResp->res.jsonValue["AdditionalDataURI"] =
447fdd26906SClaire Weinan                         entriesPath + entryID + "/attachment";
448fdd26906SClaire Weinan                     asyncResp->res.jsonValue["AdditionalDataSizeBytes"] = size;
4495cb1dd27SAsmitha Karunanithi                 }
4505cb1dd27SAsmitha Karunanithi             }
451e05aec50SEd Tanous             if (!foundDumpEntry)
452b47452b2SAsmitha Karunanithi             {
45362598e31SEd Tanous                 BMCWEB_LOG_WARNING("Can't find Dump Entry {}", entryID);
454b90d14f2SMyung Bae                 messages::resourceNotFound(asyncResp->res, dumpType + " dump",
455b90d14f2SMyung Bae                                            entryID);
456b47452b2SAsmitha Karunanithi                 return;
457b47452b2SAsmitha Karunanithi             }
4585eb468daSGeorge Liu         });
4595cb1dd27SAsmitha Karunanithi }
4605cb1dd27SAsmitha Karunanithi 
4618d1b46d7Szhanghch05 inline void deleteDumpEntry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
4629878256fSStanley Chu                             const std::string& entryID,
463b47452b2SAsmitha Karunanithi                             const std::string& dumpType)
4645cb1dd27SAsmitha Karunanithi {
4655a39f77aSPatrick Williams     auto respHandler = [asyncResp,
4665a39f77aSPatrick Williams                         entryID](const boost::system::error_code& ec) {
46762598e31SEd Tanous         BMCWEB_LOG_DEBUG("Dump Entry doDelete callback: Done");
4685cb1dd27SAsmitha Karunanithi         if (ec)
4695cb1dd27SAsmitha Karunanithi         {
4703de8d8baSGeorge Liu             if (ec.value() == EBADR)
4713de8d8baSGeorge Liu             {
4723de8d8baSGeorge Liu                 messages::resourceNotFound(asyncResp->res, "LogEntry", entryID);
4733de8d8baSGeorge Liu                 return;
4743de8d8baSGeorge Liu             }
47562598e31SEd Tanous             BMCWEB_LOG_ERROR(
47662598e31SEd Tanous                 "Dump (DBus) doDelete respHandler got error {} entryID={}", ec,
47762598e31SEd Tanous                 entryID);
4785cb1dd27SAsmitha Karunanithi             messages::internalError(asyncResp->res);
4795cb1dd27SAsmitha Karunanithi             return;
4805cb1dd27SAsmitha Karunanithi         }
4815cb1dd27SAsmitha Karunanithi     };
48218f8f608SEd Tanous 
483177612aaSEd Tanous     dbus::utility::async_method_call(
484177612aaSEd Tanous         asyncResp, respHandler, "xyz.openbmc_project.Dump.Manager",
48518f8f608SEd Tanous         std::format("{}/entry/{}", getDumpPath(dumpType), entryID),
4865cb1dd27SAsmitha Karunanithi         "xyz.openbmc_project.Object.Delete", "Delete");
4875cb1dd27SAsmitha Karunanithi }
488168d1b1aSCarson Labrado 
489504af5a0SPatrick Williams inline void downloadDumpEntry(
490504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
491168d1b1aSCarson Labrado     const std::string& entryID, const std::string& dumpType)
492168d1b1aSCarson Labrado {
493168d1b1aSCarson Labrado     if (dumpType != "BMC")
494168d1b1aSCarson Labrado     {
495168d1b1aSCarson Labrado         BMCWEB_LOG_WARNING("Can't find Dump Entry {}", entryID);
496168d1b1aSCarson Labrado         messages::resourceNotFound(asyncResp->res, dumpType + " dump", entryID);
497168d1b1aSCarson Labrado         return;
498168d1b1aSCarson Labrado     }
499168d1b1aSCarson Labrado 
500bd79bce8SPatrick Williams     std::string dumpEntryPath =
501bd79bce8SPatrick Williams         std::format("{}/entry/{}", getDumpPath(dumpType), entryID);
502168d1b1aSCarson Labrado 
503168d1b1aSCarson Labrado     auto downloadDumpEntryHandler =
504168d1b1aSCarson Labrado         [asyncResp, entryID,
505168d1b1aSCarson Labrado          dumpType](const boost::system::error_code& ec,
506168d1b1aSCarson Labrado                    const sdbusplus::message::unix_fd& unixfd) {
507ff35df94SOliver Brewka             log_services_utils::downloadEntryCallback(asyncResp, entryID,
508ff35df94SOliver Brewka                                                       dumpType, ec, unixfd);
509168d1b1aSCarson Labrado         };
510168d1b1aSCarson Labrado 
511177612aaSEd Tanous     dbus::utility::async_method_call(
512177612aaSEd Tanous         asyncResp, std::move(downloadDumpEntryHandler),
513177612aaSEd Tanous         "xyz.openbmc_project.Dump.Manager", dumpEntryPath,
514177612aaSEd Tanous         "xyz.openbmc_project.Dump.Entry", "GetFileHandle");
515168d1b1aSCarson Labrado }
516168d1b1aSCarson Labrado 
517504af5a0SPatrick Williams inline DumpCreationProgress mapDbusStatusToDumpProgress(
518504af5a0SPatrick Williams     const std::string& status)
519a43be80fSAsmitha Karunanithi {
5208e31778eSAsmitha Karunanithi     if (status ==
5218e31778eSAsmitha Karunanithi             "xyz.openbmc_project.Common.Progress.OperationStatus.Failed" ||
5228e31778eSAsmitha Karunanithi         status == "xyz.openbmc_project.Common.Progress.OperationStatus.Aborted")
5238e31778eSAsmitha Karunanithi     {
5248e31778eSAsmitha Karunanithi         return DumpCreationProgress::DUMP_CREATE_FAILED;
5258e31778eSAsmitha Karunanithi     }
5268e31778eSAsmitha Karunanithi     if (status ==
5278e31778eSAsmitha Karunanithi         "xyz.openbmc_project.Common.Progress.OperationStatus.Completed")
5288e31778eSAsmitha Karunanithi     {
5298e31778eSAsmitha Karunanithi         return DumpCreationProgress::DUMP_CREATE_SUCCESS;
5308e31778eSAsmitha Karunanithi     }
5318e31778eSAsmitha Karunanithi     return DumpCreationProgress::DUMP_CREATE_INPROGRESS;
5328e31778eSAsmitha Karunanithi }
5338e31778eSAsmitha Karunanithi 
534504af5a0SPatrick Williams inline DumpCreationProgress getDumpCompletionStatus(
535504af5a0SPatrick Williams     const dbus::utility::DBusPropertiesMap& values)
5368e31778eSAsmitha Karunanithi {
5378e31778eSAsmitha Karunanithi     for (const auto& [key, val] : values)
5388e31778eSAsmitha Karunanithi     {
5398e31778eSAsmitha Karunanithi         if (key == "Status")
5408e31778eSAsmitha Karunanithi         {
5418e31778eSAsmitha Karunanithi             const std::string* value = std::get_if<std::string>(&val);
5428e31778eSAsmitha Karunanithi             if (value == nullptr)
5438e31778eSAsmitha Karunanithi             {
54462598e31SEd Tanous                 BMCWEB_LOG_ERROR("Status property value is null");
5458e31778eSAsmitha Karunanithi                 return DumpCreationProgress::DUMP_CREATE_FAILED;
5468e31778eSAsmitha Karunanithi             }
5478e31778eSAsmitha Karunanithi             return mapDbusStatusToDumpProgress(*value);
5488e31778eSAsmitha Karunanithi         }
5498e31778eSAsmitha Karunanithi     }
5508e31778eSAsmitha Karunanithi     return DumpCreationProgress::DUMP_CREATE_INPROGRESS;
5518e31778eSAsmitha Karunanithi }
5528e31778eSAsmitha Karunanithi 
5538e31778eSAsmitha Karunanithi inline std::string getDumpEntryPath(const std::string& dumpPath)
5548e31778eSAsmitha Karunanithi {
5558e31778eSAsmitha Karunanithi     if (dumpPath == "/xyz/openbmc_project/dump/bmc/entry")
5568e31778eSAsmitha Karunanithi     {
557253f11b8SEd Tanous         return std::format("/redfish/v1/Managers/{}/LogServices/Dump/Entries/",
5589f565090SEd Tanous                            BMCWEB_REDFISH_MANAGER_URI_NAME);
5598e31778eSAsmitha Karunanithi     }
5608e31778eSAsmitha Karunanithi     if (dumpPath == "/xyz/openbmc_project/dump/system/entry")
5618e31778eSAsmitha Karunanithi     {
562253f11b8SEd Tanous         return std::format("/redfish/v1/Systems/{}/LogServices/Dump/Entries/",
563253f11b8SEd Tanous                            BMCWEB_REDFISH_SYSTEM_URI_NAME);
5648e31778eSAsmitha Karunanithi     }
5658e31778eSAsmitha Karunanithi     return "";
5668e31778eSAsmitha Karunanithi }
5678e31778eSAsmitha Karunanithi 
5688e31778eSAsmitha Karunanithi inline void createDumpTaskCallback(
5698e31778eSAsmitha Karunanithi     task::Payload&& payload,
5708e31778eSAsmitha Karunanithi     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
5718e31778eSAsmitha Karunanithi     const sdbusplus::message::object_path& createdObjPath)
5728e31778eSAsmitha Karunanithi {
5738e31778eSAsmitha Karunanithi     const std::string dumpPath = createdObjPath.parent_path().str;
5748e31778eSAsmitha Karunanithi     const std::string dumpId = createdObjPath.filename();
5758e31778eSAsmitha Karunanithi 
5768e31778eSAsmitha Karunanithi     std::string dumpEntryPath = getDumpEntryPath(dumpPath);
5778e31778eSAsmitha Karunanithi 
5788e31778eSAsmitha Karunanithi     if (dumpEntryPath.empty())
5798e31778eSAsmitha Karunanithi     {
58062598e31SEd Tanous         BMCWEB_LOG_ERROR("Invalid dump type received");
5818e31778eSAsmitha Karunanithi         messages::internalError(asyncResp->res);
5828e31778eSAsmitha Karunanithi         return;
5838e31778eSAsmitha Karunanithi     }
5848e31778eSAsmitha Karunanithi 
585177612aaSEd Tanous     dbus::utility::async_method_call(
586177612aaSEd Tanous         asyncResp,
5878cb2c024SEd Tanous         [asyncResp, payload = std::move(payload), createdObjPath,
5888e31778eSAsmitha Karunanithi          dumpEntryPath{std::move(dumpEntryPath)},
5895e7e2dc5SEd Tanous          dumpId](const boost::system::error_code& ec,
5908e31778eSAsmitha Karunanithi                  const std::string& introspectXml) {
5918e31778eSAsmitha Karunanithi             if (ec)
5928e31778eSAsmitha Karunanithi             {
59362598e31SEd Tanous                 BMCWEB_LOG_ERROR("Introspect call failed with error: {}",
59462598e31SEd Tanous                                  ec.message());
5958e31778eSAsmitha Karunanithi                 messages::internalError(asyncResp->res);
5968e31778eSAsmitha Karunanithi                 return;
5978e31778eSAsmitha Karunanithi             }
5988e31778eSAsmitha Karunanithi 
5998e31778eSAsmitha Karunanithi             // Check if the created dump object has implemented Progress
6008e31778eSAsmitha Karunanithi             // interface to track dump completion. If yes, fetch the "Status"
6018e31778eSAsmitha Karunanithi             // property of the interface, modify the task state accordingly.
6028e31778eSAsmitha Karunanithi             // Else, return task completed.
6038e31778eSAsmitha Karunanithi             tinyxml2::XMLDocument doc;
6048e31778eSAsmitha Karunanithi 
6058e31778eSAsmitha Karunanithi             doc.Parse(introspectXml.data(), introspectXml.size());
6068e31778eSAsmitha Karunanithi             tinyxml2::XMLNode* pRoot = doc.FirstChildElement("node");
6078e31778eSAsmitha Karunanithi             if (pRoot == nullptr)
6088e31778eSAsmitha Karunanithi             {
60962598e31SEd Tanous                 BMCWEB_LOG_ERROR("XML document failed to parse");
6108e31778eSAsmitha Karunanithi                 messages::internalError(asyncResp->res);
6118e31778eSAsmitha Karunanithi                 return;
6128e31778eSAsmitha Karunanithi             }
6138e31778eSAsmitha Karunanithi             tinyxml2::XMLElement* interfaceNode =
6148e31778eSAsmitha Karunanithi                 pRoot->FirstChildElement("interface");
6158e31778eSAsmitha Karunanithi 
6168e31778eSAsmitha Karunanithi             bool isProgressIntfPresent = false;
6178e31778eSAsmitha Karunanithi             while (interfaceNode != nullptr)
6188e31778eSAsmitha Karunanithi             {
619bd79bce8SPatrick Williams                 const char* thisInterfaceName =
620bd79bce8SPatrick Williams                     interfaceNode->Attribute("name");
6218e31778eSAsmitha Karunanithi                 if (thisInterfaceName != nullptr)
6228e31778eSAsmitha Karunanithi                 {
6238e31778eSAsmitha Karunanithi                     if (thisInterfaceName ==
6248e31778eSAsmitha Karunanithi                         std::string_view("xyz.openbmc_project.Common.Progress"))
6258e31778eSAsmitha Karunanithi                     {
6268e31778eSAsmitha Karunanithi                         interfaceNode =
6278e31778eSAsmitha Karunanithi                             interfaceNode->NextSiblingElement("interface");
6288e31778eSAsmitha Karunanithi                         continue;
6298e31778eSAsmitha Karunanithi                     }
6308e31778eSAsmitha Karunanithi                     isProgressIntfPresent = true;
6318e31778eSAsmitha Karunanithi                     break;
6328e31778eSAsmitha Karunanithi                 }
6338e31778eSAsmitha Karunanithi                 interfaceNode = interfaceNode->NextSiblingElement("interface");
6348e31778eSAsmitha Karunanithi             }
6358e31778eSAsmitha Karunanithi 
636a43be80fSAsmitha Karunanithi             std::shared_ptr<task::TaskData> task = task::TaskData::createTask(
6378e31778eSAsmitha Karunanithi                 [createdObjPath, dumpEntryPath, dumpId, isProgressIntfPresent](
638bd79bce8SPatrick Williams                     const boost::system::error_code& ec2,
639bd79bce8SPatrick Williams                     sdbusplus::message_t& msg,
640a43be80fSAsmitha Karunanithi                     const std::shared_ptr<task::TaskData>& taskData) {
6418b24275dSEd Tanous                     if (ec2)
642cb13a392SEd Tanous                     {
64362598e31SEd Tanous                         BMCWEB_LOG_ERROR("{}: Error in creating dump",
64462598e31SEd Tanous                                          createdObjPath.str);
645bd79bce8SPatrick Williams                         taskData->messages.emplace_back(
646bd79bce8SPatrick Williams                             messages::internalError());
6476145ed6fSAsmitha Karunanithi                         taskData->state = "Cancelled";
6486145ed6fSAsmitha Karunanithi                         return task::completed;
649cb13a392SEd Tanous                     }
650b9d36b47SEd Tanous 
6518e31778eSAsmitha Karunanithi                     if (isProgressIntfPresent)
652a43be80fSAsmitha Karunanithi                     {
6538e31778eSAsmitha Karunanithi                         dbus::utility::DBusPropertiesMap values;
6548e31778eSAsmitha Karunanithi                         std::string prop;
6558e31778eSAsmitha Karunanithi                         msg.read(prop, values);
6568e31778eSAsmitha Karunanithi 
6578e31778eSAsmitha Karunanithi                         DumpCreationProgress dumpStatus =
6588e31778eSAsmitha Karunanithi                             getDumpCompletionStatus(values);
659bd79bce8SPatrick Williams                         if (dumpStatus ==
660bd79bce8SPatrick Williams                             DumpCreationProgress::DUMP_CREATE_FAILED)
6618e31778eSAsmitha Karunanithi                         {
66262598e31SEd Tanous                             BMCWEB_LOG_ERROR("{}: Error in creating dump",
66362598e31SEd Tanous                                              createdObjPath.str);
6648e31778eSAsmitha Karunanithi                             taskData->state = "Cancelled";
6658e31778eSAsmitha Karunanithi                             return task::completed;
6668e31778eSAsmitha Karunanithi                         }
6678e31778eSAsmitha Karunanithi 
668bd79bce8SPatrick Williams                         if (dumpStatus ==
669bd79bce8SPatrick Williams                             DumpCreationProgress::DUMP_CREATE_INPROGRESS)
6708e31778eSAsmitha Karunanithi                         {
671bd79bce8SPatrick Williams                             BMCWEB_LOG_DEBUG(
672bd79bce8SPatrick Williams                                 "{}: Dump creation task is in progress",
67362598e31SEd Tanous                                 createdObjPath.str);
6748e31778eSAsmitha Karunanithi                             return !task::completed;
6758e31778eSAsmitha Karunanithi                         }
6768e31778eSAsmitha Karunanithi                     }
6778e31778eSAsmitha Karunanithi 
678a43be80fSAsmitha Karunanithi                     nlohmann::json retMessage = messages::success();
679a43be80fSAsmitha Karunanithi                     taskData->messages.emplace_back(retMessage);
680a43be80fSAsmitha Karunanithi 
681c51a58eeSEd Tanous                     boost::urls::url url = boost::urls::format(
682253f11b8SEd Tanous                         "/redfish/v1/Managers/{}/LogServices/Dump/Entries/{}",
683253f11b8SEd Tanous                         BMCWEB_REDFISH_MANAGER_URI_NAME, dumpId);
684c51a58eeSEd Tanous 
685c51a58eeSEd Tanous                     std::string headerLoc = "Location: ";
686c51a58eeSEd Tanous                     headerLoc += url.buffer();
687c51a58eeSEd Tanous 
688bd79bce8SPatrick Williams                     taskData->payload->httpHeaders.emplace_back(
689bd79bce8SPatrick Williams                         std::move(headerLoc));
690a43be80fSAsmitha Karunanithi 
69162598e31SEd Tanous                     BMCWEB_LOG_DEBUG("{}: Dump creation task completed",
69262598e31SEd Tanous                                      createdObjPath.str);
693a43be80fSAsmitha Karunanithi                     taskData->state = "Completed";
694b47452b2SAsmitha Karunanithi                     return task::completed;
695a43be80fSAsmitha Karunanithi                 },
6968e31778eSAsmitha Karunanithi                 "type='signal',interface='org.freedesktop.DBus.Properties',"
6978e31778eSAsmitha Karunanithi                 "member='PropertiesChanged',path='" +
6988e31778eSAsmitha Karunanithi                     createdObjPath.str + "'");
699a43be80fSAsmitha Karunanithi 
7008e31778eSAsmitha Karunanithi             // The task timer is set to max time limit within which the
7018e31778eSAsmitha Karunanithi             // requested dump will be collected.
7028e31778eSAsmitha Karunanithi             task->startTimer(std::chrono::minutes(6));
7038e31778eSAsmitha Karunanithi             task->payload.emplace(payload);
70429e2bdd7SChinmay Shripad Hegde             task->populateResp(asyncResp->res);
7058e31778eSAsmitha Karunanithi         },
7068e31778eSAsmitha Karunanithi         "xyz.openbmc_project.Dump.Manager", createdObjPath,
7078e31778eSAsmitha Karunanithi         "org.freedesktop.DBus.Introspectable", "Introspect");
708a43be80fSAsmitha Karunanithi }
709a43be80fSAsmitha Karunanithi 
7108d1b46d7Szhanghch05 inline void createDump(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
7118d1b46d7Szhanghch05                        const crow::Request& req, const std::string& dumpType)
712a43be80fSAsmitha Karunanithi {
713fdd26906SClaire Weinan     std::string dumpPath = getDumpEntriesPath(dumpType);
714fdd26906SClaire Weinan     if (dumpPath.empty())
715a43be80fSAsmitha Karunanithi     {
716a43be80fSAsmitha Karunanithi         messages::internalError(asyncResp->res);
717a43be80fSAsmitha Karunanithi         return;
718a43be80fSAsmitha Karunanithi     }
719a43be80fSAsmitha Karunanithi 
720a43be80fSAsmitha Karunanithi     std::optional<std::string> diagnosticDataType;
721a43be80fSAsmitha Karunanithi     std::optional<std::string> oemDiagnosticDataType;
722a43be80fSAsmitha Karunanithi 
723afc474aeSMyung Bae     if (!redfish::json_util::readJsonAction(               //
724afc474aeSMyung Bae             req, asyncResp->res,                           //
725afc474aeSMyung Bae             "DiagnosticDataType", diagnosticDataType,      //
726afc474aeSMyung Bae             "OEMDiagnosticDataType", oemDiagnosticDataType //
727afc474aeSMyung Bae             ))
728a43be80fSAsmitha Karunanithi     {
729a43be80fSAsmitha Karunanithi         return;
730a43be80fSAsmitha Karunanithi     }
731a43be80fSAsmitha Karunanithi 
732a43be80fSAsmitha Karunanithi     if (dumpType == "System")
733a43be80fSAsmitha Karunanithi     {
734a43be80fSAsmitha Karunanithi         if (!oemDiagnosticDataType || !diagnosticDataType)
735a43be80fSAsmitha Karunanithi         {
73662598e31SEd Tanous             BMCWEB_LOG_ERROR(
73762598e31SEd Tanous                 "CreateDump action parameter 'DiagnosticDataType'/'OEMDiagnosticDataType' value not found!");
738a43be80fSAsmitha Karunanithi             messages::actionParameterMissing(
739a43be80fSAsmitha Karunanithi                 asyncResp->res, "CollectDiagnosticData",
740a43be80fSAsmitha Karunanithi                 "DiagnosticDataType & OEMDiagnosticDataType");
741a43be80fSAsmitha Karunanithi             return;
742a43be80fSAsmitha Karunanithi         }
7433174e4dfSEd Tanous         if ((*oemDiagnosticDataType != "System") ||
744a43be80fSAsmitha Karunanithi             (*diagnosticDataType != "OEM"))
745a43be80fSAsmitha Karunanithi         {
74662598e31SEd Tanous             BMCWEB_LOG_ERROR("Wrong parameter values passed");
747ace85d60SEd Tanous             messages::internalError(asyncResp->res);
748a43be80fSAsmitha Karunanithi             return;
749a43be80fSAsmitha Karunanithi         }
750253f11b8SEd Tanous         dumpPath = std::format("/redfish/v1/Systems/{}/LogServices/Dump/",
751253f11b8SEd Tanous                                BMCWEB_REDFISH_SYSTEM_URI_NAME);
752a43be80fSAsmitha Karunanithi     }
753a43be80fSAsmitha Karunanithi     else if (dumpType == "BMC")
754a43be80fSAsmitha Karunanithi     {
755a43be80fSAsmitha Karunanithi         if (!diagnosticDataType)
756a43be80fSAsmitha Karunanithi         {
75762598e31SEd Tanous             BMCWEB_LOG_ERROR(
75862598e31SEd Tanous                 "CreateDump action parameter 'DiagnosticDataType' not found!");
759a43be80fSAsmitha Karunanithi             messages::actionParameterMissing(
760a43be80fSAsmitha Karunanithi                 asyncResp->res, "CollectDiagnosticData", "DiagnosticDataType");
761a43be80fSAsmitha Karunanithi             return;
762a43be80fSAsmitha Karunanithi         }
7633174e4dfSEd Tanous         if (*diagnosticDataType != "Manager")
764a43be80fSAsmitha Karunanithi         {
76562598e31SEd Tanous             BMCWEB_LOG_ERROR(
76662598e31SEd Tanous                 "Wrong parameter value passed for 'DiagnosticDataType'");
767ace85d60SEd Tanous             messages::internalError(asyncResp->res);
768a43be80fSAsmitha Karunanithi             return;
769a43be80fSAsmitha Karunanithi         }
770253f11b8SEd Tanous         dumpPath = std::format("/redfish/v1/Managers/{}/LogServices/Dump/",
771253f11b8SEd Tanous                                BMCWEB_REDFISH_MANAGER_URI_NAME);
7725907571dSAsmitha Karunanithi     }
7735907571dSAsmitha Karunanithi     else
7745907571dSAsmitha Karunanithi     {
77562598e31SEd Tanous         BMCWEB_LOG_ERROR("CreateDump failed. Unknown dump type");
7765907571dSAsmitha Karunanithi         messages::internalError(asyncResp->res);
7775907571dSAsmitha Karunanithi         return;
778a43be80fSAsmitha Karunanithi     }
779a43be80fSAsmitha Karunanithi 
7808e31778eSAsmitha Karunanithi     std::vector<std::pair<std::string, std::variant<std::string, uint64_t>>>
7818e31778eSAsmitha Karunanithi         createDumpParamVec;
7828e31778eSAsmitha Karunanithi 
783f574a8e1SCarson Labrado     if (req.session != nullptr)
784f574a8e1SCarson Labrado     {
78568dd075aSAsmitha Karunanithi         createDumpParamVec.emplace_back(
78668dd075aSAsmitha Karunanithi             "xyz.openbmc_project.Dump.Create.CreateParameters.OriginatorId",
78768dd075aSAsmitha Karunanithi             req.session->clientIp);
78868dd075aSAsmitha Karunanithi         createDumpParamVec.emplace_back(
78968dd075aSAsmitha Karunanithi             "xyz.openbmc_project.Dump.Create.CreateParameters.OriginatorType",
79068dd075aSAsmitha Karunanithi             "xyz.openbmc_project.Common.OriginatedBy.OriginatorTypes.Client");
791f574a8e1SCarson Labrado     }
79268dd075aSAsmitha Karunanithi 
793177612aaSEd Tanous     dbus::utility::async_method_call(
794177612aaSEd Tanous         asyncResp,
7955e7e2dc5SEd Tanous         [asyncResp, payload(task::Payload(req)),
7965e7e2dc5SEd Tanous          dumpPath](const boost::system::error_code& ec,
7975e7e2dc5SEd Tanous                    const sdbusplus::message_t& msg,
7988e31778eSAsmitha Karunanithi                    const sdbusplus::message::object_path& objPath) mutable {
799a43be80fSAsmitha Karunanithi             if (ec)
800a43be80fSAsmitha Karunanithi             {
80162598e31SEd Tanous                 BMCWEB_LOG_ERROR("CreateDump resp_handler got error {}", ec);
8025907571dSAsmitha Karunanithi                 const sd_bus_error* dbusError = msg.get_error();
8035907571dSAsmitha Karunanithi                 if (dbusError == nullptr)
8045907571dSAsmitha Karunanithi                 {
8055907571dSAsmitha Karunanithi                     messages::internalError(asyncResp->res);
8065907571dSAsmitha Karunanithi                     return;
8075907571dSAsmitha Karunanithi                 }
8085907571dSAsmitha Karunanithi 
80962598e31SEd Tanous                 BMCWEB_LOG_ERROR("CreateDump DBus error: {} and error msg: {}",
81062598e31SEd Tanous                                  dbusError->name, dbusError->message);
8115907571dSAsmitha Karunanithi                 if (std::string_view(
8125907571dSAsmitha Karunanithi                         "xyz.openbmc_project.Common.Error.NotAllowed") ==
8135907571dSAsmitha Karunanithi                     dbusError->name)
8145907571dSAsmitha Karunanithi                 {
8155907571dSAsmitha Karunanithi                     messages::resourceInStandby(asyncResp->res);
8165907571dSAsmitha Karunanithi                     return;
8175907571dSAsmitha Karunanithi                 }
8185907571dSAsmitha Karunanithi                 if (std::string_view(
8195907571dSAsmitha Karunanithi                         "xyz.openbmc_project.Dump.Create.Error.Disabled") ==
8205907571dSAsmitha Karunanithi                     dbusError->name)
8215907571dSAsmitha Karunanithi                 {
8225907571dSAsmitha Karunanithi                     messages::serviceDisabled(asyncResp->res, dumpPath);
8235907571dSAsmitha Karunanithi                     return;
8245907571dSAsmitha Karunanithi                 }
8255907571dSAsmitha Karunanithi                 if (std::string_view(
8265907571dSAsmitha Karunanithi                         "xyz.openbmc_project.Common.Error.Unavailable") ==
8275907571dSAsmitha Karunanithi                     dbusError->name)
8285907571dSAsmitha Karunanithi                 {
8295907571dSAsmitha Karunanithi                     messages::resourceInUse(asyncResp->res);
8305907571dSAsmitha Karunanithi                     return;
8315907571dSAsmitha Karunanithi                 }
8325907571dSAsmitha Karunanithi                 // Other Dbus errors such as:
8335907571dSAsmitha Karunanithi                 // xyz.openbmc_project.Common.Error.InvalidArgument &
8345907571dSAsmitha Karunanithi                 // org.freedesktop.DBus.Error.InvalidArgs are all related to
8355907571dSAsmitha Karunanithi                 // the dbus call that is made here in the bmcweb
8365907571dSAsmitha Karunanithi                 // implementation and has nothing to do with the client's
8375907571dSAsmitha Karunanithi                 // input in the request. Hence, returning internal error
8385907571dSAsmitha Karunanithi                 // back to the client.
839a43be80fSAsmitha Karunanithi                 messages::internalError(asyncResp->res);
840a43be80fSAsmitha Karunanithi                 return;
841a43be80fSAsmitha Karunanithi             }
84262598e31SEd Tanous             BMCWEB_LOG_DEBUG("Dump Created. Path: {}", objPath.str);
8438e31778eSAsmitha Karunanithi             createDumpTaskCallback(std::move(payload), asyncResp, objPath);
844a43be80fSAsmitha Karunanithi         },
84518f8f608SEd Tanous         "xyz.openbmc_project.Dump.Manager", getDumpPath(dumpType),
8468e31778eSAsmitha Karunanithi         "xyz.openbmc_project.Dump.Create", "CreateDump", createDumpParamVec);
847a43be80fSAsmitha Karunanithi }
848a43be80fSAsmitha Karunanithi 
8498d1b46d7Szhanghch05 inline void clearDump(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
8508d1b46d7Szhanghch05                       const std::string& dumpType)
85180319af1SAsmitha Karunanithi {
852177612aaSEd Tanous     dbus::utility::async_method_call(
853177612aaSEd Tanous         asyncResp,
8540d946211SClaire Weinan         [asyncResp](const boost::system::error_code& ec) {
85580319af1SAsmitha Karunanithi             if (ec)
85680319af1SAsmitha Karunanithi             {
85762598e31SEd Tanous                 BMCWEB_LOG_ERROR("clearDump resp_handler got error {}", ec);
85880319af1SAsmitha Karunanithi                 messages::internalError(asyncResp->res);
85980319af1SAsmitha Karunanithi                 return;
86080319af1SAsmitha Karunanithi             }
861e2460466SAmy Chang             messages::success(asyncResp->res);
8620d946211SClaire Weinan         },
86318f8f608SEd Tanous         "xyz.openbmc_project.Dump.Manager", getDumpPath(dumpType),
8640d946211SClaire Weinan         "xyz.openbmc_project.Collection.DeleteAll", "DeleteAll");
86580319af1SAsmitha Karunanithi }
86680319af1SAsmitha Karunanithi 
867bd79bce8SPatrick Williams inline void parseCrashdumpParameters(
868bd79bce8SPatrick Williams     const dbus::utility::DBusPropertiesMap& params, std::string& filename,
869bd79bce8SPatrick Williams     std::string& timestamp, std::string& logfile)
870043a0536SJohnathan Mantey {
871d1bde9e5SKrzysztof Grobelny     const std::string* filenamePtr = nullptr;
872d1bde9e5SKrzysztof Grobelny     const std::string* timestampPtr = nullptr;
873d1bde9e5SKrzysztof Grobelny     const std::string* logfilePtr = nullptr;
874d1bde9e5SKrzysztof Grobelny 
875d1bde9e5SKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
876d1bde9e5SKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), params, "Timestamp", timestampPtr,
877d1bde9e5SKrzysztof Grobelny         "Filename", filenamePtr, "Log", logfilePtr);
878d1bde9e5SKrzysztof Grobelny 
879d1bde9e5SKrzysztof Grobelny     if (!success)
880043a0536SJohnathan Mantey     {
881d1bde9e5SKrzysztof Grobelny         return;
882043a0536SJohnathan Mantey     }
883d1bde9e5SKrzysztof Grobelny 
884d1bde9e5SKrzysztof Grobelny     if (filenamePtr != nullptr)
885043a0536SJohnathan Mantey     {
886d1bde9e5SKrzysztof Grobelny         filename = *filenamePtr;
887d1bde9e5SKrzysztof Grobelny     }
888d1bde9e5SKrzysztof Grobelny 
889d1bde9e5SKrzysztof Grobelny     if (timestampPtr != nullptr)
890043a0536SJohnathan Mantey     {
891d1bde9e5SKrzysztof Grobelny         timestamp = *timestampPtr;
892043a0536SJohnathan Mantey     }
893d1bde9e5SKrzysztof Grobelny 
894d1bde9e5SKrzysztof Grobelny     if (logfilePtr != nullptr)
895043a0536SJohnathan Mantey     {
896d1bde9e5SKrzysztof Grobelny         logfile = *logfilePtr;
897043a0536SJohnathan Mantey     }
898043a0536SJohnathan Mantey }
899043a0536SJohnathan Mantey 
9007e860f15SJohn Edward Broadbent inline void requestRoutesSystemLogServiceCollection(App& app)
9011da66f75SEd Tanous {
902c4bf6374SJason M. Bills     /**
903c4bf6374SJason M. Bills      * Functions triggers appropriate requests on DBus
904c4bf6374SJason M. Bills      */
90522d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/")
906ed398213SEd Tanous         .privileges(redfish::privileges::getLogServiceCollection)
907bd79bce8SPatrick Williams         .methods(
908bd79bce8SPatrick Williams             boost::beast::http::verb::
909bd79bce8SPatrick Williams                 get)([&app](const crow::Request& req,
91022d268cbSEd Tanous                             const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
91122d268cbSEd Tanous                             const std::string& systemName) {
9123ba00073SCarson Labrado             if (!redfish::setUpRedfishRoute(app, req, asyncResp))
913c4bf6374SJason M. Bills             {
91445ca1b86SEd Tanous                 return;
91545ca1b86SEd Tanous             }
91625b54dbaSEd Tanous             if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
9177f3e84a1SEd Tanous             {
9187f3e84a1SEd Tanous                 // Option currently returns no systems.  TBD
9197f3e84a1SEd Tanous                 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
9207f3e84a1SEd Tanous                                            systemName);
9217f3e84a1SEd Tanous                 return;
9227f3e84a1SEd Tanous             }
923253f11b8SEd Tanous             if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
92422d268cbSEd Tanous             {
92522d268cbSEd Tanous                 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
92622d268cbSEd Tanous                                            systemName);
92722d268cbSEd Tanous                 return;
92822d268cbSEd Tanous             }
92922d268cbSEd Tanous 
9307e860f15SJohn Edward Broadbent             // Collections don't include the static data added by SubRoute
9317e860f15SJohn Edward Broadbent             // because it has a duplicate entry for members
932c4bf6374SJason M. Bills             asyncResp->res.jsonValue["@odata.type"] =
933c4bf6374SJason M. Bills                 "#LogServiceCollection.LogServiceCollection";
934c4bf6374SJason M. Bills             asyncResp->res.jsonValue["@odata.id"] =
935253f11b8SEd Tanous                 std::format("/redfish/v1/Systems/{}/LogServices",
936253f11b8SEd Tanous                             BMCWEB_REDFISH_SYSTEM_URI_NAME);
93745ca1b86SEd Tanous             asyncResp->res.jsonValue["Name"] = "System Log Services Collection";
938c4bf6374SJason M. Bills             asyncResp->res.jsonValue["Description"] =
939c4bf6374SJason M. Bills                 "Collection of LogServices for this Computer System";
940bd79bce8SPatrick Williams             nlohmann::json& logServiceArray =
941bd79bce8SPatrick Williams                 asyncResp->res.jsonValue["Members"];
942c4bf6374SJason M. Bills             logServiceArray = nlohmann::json::array();
9431476687dSEd Tanous             nlohmann::json::object_t eventLog;
9441476687dSEd Tanous             eventLog["@odata.id"] =
945253f11b8SEd Tanous                 std::format("/redfish/v1/Systems/{}/LogServices/EventLog",
946253f11b8SEd Tanous                             BMCWEB_REDFISH_SYSTEM_URI_NAME);
947b2ba3072SPatrick Williams             logServiceArray.emplace_back(std::move(eventLog));
94825b54dbaSEd Tanous             if constexpr (BMCWEB_REDFISH_DUMP_LOG)
94925b54dbaSEd Tanous             {
9501476687dSEd Tanous                 nlohmann::json::object_t dumpLog;
95125b54dbaSEd Tanous                 dumpLog["@odata.id"] =
952253f11b8SEd Tanous                     std::format("/redfish/v1/Systems/{}/LogServices/Dump",
953253f11b8SEd Tanous                                 BMCWEB_REDFISH_SYSTEM_URI_NAME);
954b2ba3072SPatrick Williams                 logServiceArray.emplace_back(std::move(dumpLog));
95525b54dbaSEd Tanous             }
956c9bb6861Sraviteja-b 
9575ffd11f2SGunnar Mills             if constexpr (BMCWEB_REDFISH_CPU_LOG)
95825b54dbaSEd Tanous             {
9591476687dSEd Tanous                 nlohmann::json::object_t crashdump;
9601476687dSEd Tanous                 crashdump["@odata.id"] =
961253f11b8SEd Tanous                     std::format("/redfish/v1/Systems/{}/LogServices/Crashdump",
962253f11b8SEd Tanous                                 BMCWEB_REDFISH_SYSTEM_URI_NAME);
963b2ba3072SPatrick Williams                 logServiceArray.emplace_back(std::move(crashdump));
96425b54dbaSEd Tanous             }
965b7028ebfSSpencer Ku 
96625b54dbaSEd Tanous             if constexpr (BMCWEB_REDFISH_HOST_LOGGER)
96725b54dbaSEd Tanous             {
9681476687dSEd Tanous                 nlohmann::json::object_t hostlogger;
9691476687dSEd Tanous                 hostlogger["@odata.id"] =
970253f11b8SEd Tanous                     std::format("/redfish/v1/Systems/{}/LogServices/HostLogger",
971253f11b8SEd Tanous                                 BMCWEB_REDFISH_SYSTEM_URI_NAME);
972b2ba3072SPatrick Williams                 logServiceArray.emplace_back(std::move(hostlogger));
97325b54dbaSEd Tanous             }
974c4bf6374SJason M. Bills             asyncResp->res.jsonValue["Members@odata.count"] =
975c4bf6374SJason M. Bills                 logServiceArray.size();
976a3316fc6SZhikuiRen 
9777a1dbc48SGeorge Liu             constexpr std::array<std::string_view, 1> interfaces = {
9787a1dbc48SGeorge Liu                 "xyz.openbmc_project.State.Boot.PostCode"};
9797a1dbc48SGeorge Liu             dbus::utility::getSubTreePaths(
9807a1dbc48SGeorge Liu                 "/", 0, interfaces,
9817a1dbc48SGeorge Liu                 [asyncResp](const boost::system::error_code& ec,
982b9d36b47SEd Tanous                             const dbus::utility::MapperGetSubTreePathsResponse&
983b9d36b47SEd Tanous                                 subtreePath) {
984a3316fc6SZhikuiRen                     if (ec)
985a3316fc6SZhikuiRen                     {
98662598e31SEd Tanous                         BMCWEB_LOG_ERROR("{}", ec);
987a3316fc6SZhikuiRen                         return;
988a3316fc6SZhikuiRen                     }
989a3316fc6SZhikuiRen 
99055f79e6fSEd Tanous                     for (const auto& pathStr : subtreePath)
991a3316fc6SZhikuiRen                     {
992a3316fc6SZhikuiRen                         if (pathStr.find("PostCode") != std::string::npos)
993a3316fc6SZhikuiRen                         {
99423a21a1cSEd Tanous                             nlohmann::json& logServiceArrayLocal =
995a3316fc6SZhikuiRen                                 asyncResp->res.jsonValue["Members"];
996613dabeaSEd Tanous                             nlohmann::json::object_t member;
997253f11b8SEd Tanous                             member["@odata.id"] = std::format(
998253f11b8SEd Tanous                                 "/redfish/v1/Systems/{}/LogServices/PostCodes",
999253f11b8SEd Tanous                                 BMCWEB_REDFISH_SYSTEM_URI_NAME);
1000613dabeaSEd Tanous 
1001bd79bce8SPatrick Williams                             logServiceArrayLocal.emplace_back(
1002bd79bce8SPatrick Williams                                 std::move(member));
1003613dabeaSEd Tanous 
100445ca1b86SEd Tanous                             asyncResp->res.jsonValue["Members@odata.count"] =
100523a21a1cSEd Tanous                                 logServiceArrayLocal.size();
1006a3316fc6SZhikuiRen                             return;
1007a3316fc6SZhikuiRen                         }
1008a3316fc6SZhikuiRen                     }
10097a1dbc48SGeorge Liu                 });
10107e860f15SJohn Edward Broadbent         });
1011c4bf6374SJason M. Bills }
1012c4bf6374SJason M. Bills 
10137e860f15SJohn Edward Broadbent inline void requestRoutesEventLogService(App& app)
1014c4bf6374SJason M. Bills {
101522d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/EventLog/")
1016ed398213SEd Tanous         .privileges(redfish::privileges::getLogService)
1017bd79bce8SPatrick Williams         .methods(
1018bd79bce8SPatrick Williams             boost::beast::http::verb::
1019bd79bce8SPatrick Williams                 get)([&app](const crow::Request& req,
102022d268cbSEd Tanous                             const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
102122d268cbSEd Tanous                             const std::string& systemName) {
10223ba00073SCarson Labrado             if (!redfish::setUpRedfishRoute(app, req, asyncResp))
102345ca1b86SEd Tanous             {
102445ca1b86SEd Tanous                 return;
102545ca1b86SEd Tanous             }
1026253f11b8SEd Tanous             if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
102722d268cbSEd Tanous             {
102822d268cbSEd Tanous                 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
102922d268cbSEd Tanous                                            systemName);
103022d268cbSEd Tanous                 return;
103122d268cbSEd Tanous             }
1032c4bf6374SJason M. Bills             asyncResp->res.jsonValue["@odata.id"] =
1033253f11b8SEd Tanous                 std::format("/redfish/v1/Systems/{}/LogServices/EventLog",
1034253f11b8SEd Tanous                             BMCWEB_REDFISH_SYSTEM_URI_NAME);
1035c4bf6374SJason M. Bills             asyncResp->res.jsonValue["@odata.type"] =
1036b25644a1SJanet Adkins                 "#LogService.v1_2_0.LogService";
1037c4bf6374SJason M. Bills             asyncResp->res.jsonValue["Name"] = "Event Log Service";
1038bd79bce8SPatrick Williams             asyncResp->res.jsonValue["Description"] =
1039bd79bce8SPatrick Williams                 "System Event Log Service";
1040c4bf6374SJason M. Bills             asyncResp->res.jsonValue["Id"] = "EventLog";
1041539d8c6bSEd Tanous             asyncResp->res.jsonValue["OverWritePolicy"] =
1042539d8c6bSEd Tanous                 log_service::OverWritePolicy::WrapsWhenFull;
10437c8c4058STejas Patil 
10447c8c4058STejas Patil             std::pair<std::string, std::string> redfishDateTimeOffset =
10452b82937eSEd Tanous                 redfish::time_utils::getDateTimeOffsetNow();
10467c8c4058STejas Patil 
10477c8c4058STejas Patil             asyncResp->res.jsonValue["DateTime"] = redfishDateTimeOffset.first;
10487c8c4058STejas Patil             asyncResp->res.jsonValue["DateTimeLocalOffset"] =
10497c8c4058STejas Patil                 redfishDateTimeOffset.second;
10507c8c4058STejas Patil 
1051bd79bce8SPatrick Williams             asyncResp->res.jsonValue["Entries"]["@odata.id"] = std::format(
1052bd79bce8SPatrick Williams                 "/redfish/v1/Systems/{}/LogServices/EventLog/Entries",
1053253f11b8SEd Tanous                 BMCWEB_REDFISH_SYSTEM_URI_NAME);
1054bd79bce8SPatrick Williams             asyncResp->res
1055bd79bce8SPatrick Williams                 .jsonValue["Actions"]["#LogService.ClearLog"]["target"]
1056e7d6c8b2SGunnar Mills 
105720fa6a2cSEd Tanous                 = std::format(
1058253f11b8SEd Tanous                     "/redfish/v1/Systems/{}/LogServices/EventLog/Actions/LogService.ClearLog",
105920fa6a2cSEd Tanous                     BMCWEB_REDFISH_SYSTEM_URI_NAME);
1060*08fad5d9SCorey Ethington 
1061*08fad5d9SCorey Ethington             etag_utils::setEtagOmitDateTimeHandler(asyncResp);
10627e860f15SJohn Edward Broadbent         });
1063489640c6SJason M. Bills }
1064489640c6SJason M. Bills 
1065dd72e87bSClaire Weinan inline void handleBMCLogServicesCollectionGet(
1066fdd26906SClaire Weinan     crow::App& app, const crow::Request& req,
1067253f11b8SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1068253f11b8SEd Tanous     const std::string& managerId)
10691da66f75SEd Tanous {
10703ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
107145ca1b86SEd Tanous     {
107245ca1b86SEd Tanous         return;
107345ca1b86SEd Tanous     }
1074253f11b8SEd Tanous 
1075253f11b8SEd Tanous     if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1076253f11b8SEd Tanous     {
1077253f11b8SEd Tanous         messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1078253f11b8SEd Tanous         return;
1079253f11b8SEd Tanous     }
1080253f11b8SEd Tanous 
10817e860f15SJohn Edward Broadbent     // Collections don't include the static data added by SubRoute
10827e860f15SJohn Edward Broadbent     // because it has a duplicate entry for members
1083e1f26343SJason M. Bills     asyncResp->res.jsonValue["@odata.type"] =
10841da66f75SEd Tanous         "#LogServiceCollection.LogServiceCollection";
1085253f11b8SEd Tanous     asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
1086253f11b8SEd Tanous         "/redfish/v1/Managers/{}/LogServices", BMCWEB_REDFISH_MANAGER_URI_NAME);
1087002d39b4SEd Tanous     asyncResp->res.jsonValue["Name"] = "Open BMC Log Services Collection";
1088e1f26343SJason M. Bills     asyncResp->res.jsonValue["Description"] =
10891da66f75SEd Tanous         "Collection of LogServices for this Manager";
1090002d39b4SEd Tanous     nlohmann::json& logServiceArray = asyncResp->res.jsonValue["Members"];
1091c4bf6374SJason M. Bills     logServiceArray = nlohmann::json::array();
1092fdd26906SClaire Weinan 
109325b54dbaSEd Tanous     if constexpr (BMCWEB_REDFISH_BMC_JOURNAL)
109425b54dbaSEd Tanous     {
1095613dabeaSEd Tanous         nlohmann::json::object_t journal;
1096253f11b8SEd Tanous         journal["@odata.id"] =
1097253f11b8SEd Tanous             boost::urls::format("/redfish/v1/Managers/{}/LogServices/Journal",
1098253f11b8SEd Tanous                                 BMCWEB_REDFISH_MANAGER_URI_NAME);
1099b2ba3072SPatrick Williams         logServiceArray.emplace_back(std::move(journal));
110025b54dbaSEd Tanous     }
1101fdd26906SClaire Weinan 
1102fdd26906SClaire Weinan     asyncResp->res.jsonValue["Members@odata.count"] = logServiceArray.size();
1103fdd26906SClaire Weinan 
110425b54dbaSEd Tanous     if constexpr (BMCWEB_REDFISH_DUMP_LOG)
110525b54dbaSEd Tanous     {
110615912159SGeorge Liu         constexpr std::array<std::string_view, 1> interfaces = {
11077a1dbc48SGeorge Liu             "xyz.openbmc_project.Collection.DeleteAll"};
11087a1dbc48SGeorge Liu         dbus::utility::getSubTreePaths(
11097a1dbc48SGeorge Liu             "/xyz/openbmc_project/dump", 0, interfaces,
111025b54dbaSEd Tanous             [asyncResp](const boost::system::error_code& ec,
111125b54dbaSEd Tanous                         const dbus::utility::MapperGetSubTreePathsResponse&
111225b54dbaSEd Tanous                             subTreePaths) {
1113fdd26906SClaire Weinan                 if (ec)
1114fdd26906SClaire Weinan                 {
111562598e31SEd Tanous                     BMCWEB_LOG_ERROR(
111662598e31SEd Tanous                         "handleBMCLogServicesCollectionGet respHandler got error {}",
111762598e31SEd Tanous                         ec);
1118bd79bce8SPatrick Williams                     // Assume that getting an error simply means there are no
1119bd79bce8SPatrick Williams                     // dump LogServices. Return without adding any error
1120bd79bce8SPatrick Williams                     // response.
1121fdd26906SClaire Weinan                     return;
1122fdd26906SClaire Weinan                 }
1123fdd26906SClaire Weinan 
1124fdd26906SClaire Weinan                 nlohmann::json& logServiceArrayLocal =
1125fdd26906SClaire Weinan                     asyncResp->res.jsonValue["Members"];
1126fdd26906SClaire Weinan 
1127fdd26906SClaire Weinan                 for (const std::string& path : subTreePaths)
1128fdd26906SClaire Weinan                 {
1129fdd26906SClaire Weinan                     if (path == "/xyz/openbmc_project/dump/bmc")
1130fdd26906SClaire Weinan                     {
1131613dabeaSEd Tanous                         nlohmann::json::object_t member;
1132253f11b8SEd Tanous                         member["@odata.id"] = boost::urls::format(
1133253f11b8SEd Tanous                             "/redfish/v1/Managers/{}/LogServices/Dump",
1134253f11b8SEd Tanous                             BMCWEB_REDFISH_MANAGER_URI_NAME);
1135b2ba3072SPatrick Williams                         logServiceArrayLocal.emplace_back(std::move(member));
1136fdd26906SClaire Weinan                     }
1137fdd26906SClaire Weinan                     else if (path == "/xyz/openbmc_project/dump/faultlog")
1138fdd26906SClaire Weinan                     {
1139613dabeaSEd Tanous                         nlohmann::json::object_t member;
1140253f11b8SEd Tanous                         member["@odata.id"] = boost::urls::format(
1141253f11b8SEd Tanous                             "/redfish/v1/Managers/{}/LogServices/FaultLog",
1142253f11b8SEd Tanous                             BMCWEB_REDFISH_MANAGER_URI_NAME);
1143b2ba3072SPatrick Williams                         logServiceArrayLocal.emplace_back(std::move(member));
1144fdd26906SClaire Weinan                     }
1145fdd26906SClaire Weinan                 }
1146fdd26906SClaire Weinan 
1147e1f26343SJason M. Bills                 asyncResp->res.jsonValue["Members@odata.count"] =
1148fdd26906SClaire Weinan                     logServiceArrayLocal.size();
11497a1dbc48SGeorge Liu             });
115025b54dbaSEd Tanous     }
1151fdd26906SClaire Weinan }
1152fdd26906SClaire Weinan 
1153fdd26906SClaire Weinan inline void requestRoutesBMCLogServiceCollection(App& app)
1154fdd26906SClaire Weinan {
1155253f11b8SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/LogServices/")
1156fdd26906SClaire Weinan         .privileges(redfish::privileges::getLogServiceCollection)
1157fdd26906SClaire Weinan         .methods(boost::beast::http::verb::get)(
1158dd72e87bSClaire Weinan             std::bind_front(handleBMCLogServicesCollectionGet, std::ref(app)));
1159e1f26343SJason M. Bills }
1160e1f26343SJason M. Bills 
1161504af5a0SPatrick Williams inline void getDumpServiceInfo(
1162504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1163fdd26906SClaire Weinan     const std::string& dumpType)
1164c9bb6861Sraviteja-b {
1165fdd26906SClaire Weinan     std::string dumpPath;
1166539d8c6bSEd Tanous     log_service::OverWritePolicy overWritePolicy =
1167539d8c6bSEd Tanous         log_service::OverWritePolicy::Invalid;
1168fdd26906SClaire Weinan     bool collectDiagnosticDataSupported = false;
1169fdd26906SClaire Weinan 
1170fdd26906SClaire Weinan     if (dumpType == "BMC")
117145ca1b86SEd Tanous     {
1172253f11b8SEd Tanous         dumpPath = std::format("/redfish/v1/Managers/{}/LogServices/Dump",
1173253f11b8SEd Tanous                                BMCWEB_REDFISH_MANAGER_URI_NAME);
1174539d8c6bSEd Tanous         overWritePolicy = log_service::OverWritePolicy::WrapsWhenFull;
1175fdd26906SClaire Weinan         collectDiagnosticDataSupported = true;
1176fdd26906SClaire Weinan     }
1177fdd26906SClaire Weinan     else if (dumpType == "FaultLog")
1178fdd26906SClaire Weinan     {
1179253f11b8SEd Tanous         dumpPath = std::format("/redfish/v1/Managers/{}/LogServices/FaultLog",
1180253f11b8SEd Tanous                                BMCWEB_REDFISH_MANAGER_URI_NAME);
1181539d8c6bSEd Tanous         overWritePolicy = log_service::OverWritePolicy::Unknown;
1182fdd26906SClaire Weinan         collectDiagnosticDataSupported = false;
1183fdd26906SClaire Weinan     }
1184fdd26906SClaire Weinan     else if (dumpType == "System")
1185fdd26906SClaire Weinan     {
1186253f11b8SEd Tanous         dumpPath = std::format("/redfish/v1/Systems/{}/LogServices/Dump",
1187253f11b8SEd Tanous                                BMCWEB_REDFISH_SYSTEM_URI_NAME);
1188539d8c6bSEd Tanous         overWritePolicy = log_service::OverWritePolicy::WrapsWhenFull;
1189fdd26906SClaire Weinan         collectDiagnosticDataSupported = true;
1190fdd26906SClaire Weinan     }
1191fdd26906SClaire Weinan     else
1192fdd26906SClaire Weinan     {
119362598e31SEd Tanous         BMCWEB_LOG_ERROR("getDumpServiceInfo() invalid dump type: {}",
119462598e31SEd Tanous                          dumpType);
1195fdd26906SClaire Weinan         messages::internalError(asyncResp->res);
119645ca1b86SEd Tanous         return;
119745ca1b86SEd Tanous     }
1198fdd26906SClaire Weinan 
1199fdd26906SClaire Weinan     asyncResp->res.jsonValue["@odata.id"] = dumpPath;
1200fdd26906SClaire Weinan     asyncResp->res.jsonValue["@odata.type"] = "#LogService.v1_2_0.LogService";
1201c9bb6861Sraviteja-b     asyncResp->res.jsonValue["Name"] = "Dump LogService";
1202fdd26906SClaire Weinan     asyncResp->res.jsonValue["Description"] = dumpType + " Dump LogService";
1203fdd26906SClaire Weinan     asyncResp->res.jsonValue["Id"] = std::filesystem::path(dumpPath).filename();
1204539d8c6bSEd Tanous     asyncResp->res.jsonValue["OverWritePolicy"] = overWritePolicy;
12057c8c4058STejas Patil 
12067c8c4058STejas Patil     std::pair<std::string, std::string> redfishDateTimeOffset =
12072b82937eSEd Tanous         redfish::time_utils::getDateTimeOffsetNow();
12080fda0f12SGeorge Liu     asyncResp->res.jsonValue["DateTime"] = redfishDateTimeOffset.first;
12097c8c4058STejas Patil     asyncResp->res.jsonValue["DateTimeLocalOffset"] =
12107c8c4058STejas Patil         redfishDateTimeOffset.second;
12117c8c4058STejas Patil 
1212fdd26906SClaire Weinan     asyncResp->res.jsonValue["Entries"]["@odata.id"] = dumpPath + "/Entries";
1213fdd26906SClaire Weinan 
1214fdd26906SClaire Weinan     if (collectDiagnosticDataSupported)
1215fdd26906SClaire Weinan     {
1216002d39b4SEd Tanous         asyncResp->res.jsonValue["Actions"]["#LogService.CollectDiagnosticData"]
12171476687dSEd Tanous                                 ["target"] =
1218fdd26906SClaire Weinan             dumpPath + "/Actions/LogService.CollectDiagnosticData";
1219fdd26906SClaire Weinan     }
12200d946211SClaire Weinan 
1221*08fad5d9SCorey Ethington     etag_utils::setEtagOmitDateTimeHandler(asyncResp);
1222*08fad5d9SCorey Ethington 
12230d946211SClaire Weinan     constexpr std::array<std::string_view, 1> interfaces = {deleteAllInterface};
12240d946211SClaire Weinan     dbus::utility::getSubTreePaths(
12250d946211SClaire Weinan         "/xyz/openbmc_project/dump", 0, interfaces,
12260d946211SClaire Weinan         [asyncResp, dumpType, dumpPath](
12270d946211SClaire Weinan             const boost::system::error_code& ec,
12280d946211SClaire Weinan             const dbus::utility::MapperGetSubTreePathsResponse& subTreePaths) {
12290d946211SClaire Weinan             if (ec)
12300d946211SClaire Weinan             {
1231bd79bce8SPatrick Williams                 BMCWEB_LOG_ERROR("getDumpServiceInfo respHandler got error {}",
1232bd79bce8SPatrick Williams                                  ec);
12330d946211SClaire Weinan                 // Assume that getting an error simply means there are no dump
12340d946211SClaire Weinan                 // LogServices. Return without adding any error response.
12350d946211SClaire Weinan                 return;
12360d946211SClaire Weinan             }
123718f8f608SEd Tanous             std::string dbusDumpPath = getDumpPath(dumpType);
12380d946211SClaire Weinan             for (const std::string& path : subTreePaths)
12390d946211SClaire Weinan             {
12400d946211SClaire Weinan                 if (path == dbusDumpPath)
12410d946211SClaire Weinan                 {
1242bd79bce8SPatrick Williams                     asyncResp->res.jsonValue["Actions"]["#LogService.ClearLog"]
1243bd79bce8SPatrick Williams                                             ["target"] =
12440d946211SClaire Weinan                         dumpPath + "/Actions/LogService.ClearLog";
12450d946211SClaire Weinan                     break;
12460d946211SClaire Weinan                 }
12470d946211SClaire Weinan             }
12480d946211SClaire Weinan         });
1249c9bb6861Sraviteja-b }
1250c9bb6861Sraviteja-b 
1251fdd26906SClaire Weinan inline void handleLogServicesDumpServiceGet(
1252fdd26906SClaire Weinan     crow::App& app, const std::string& dumpType, const crow::Request& req,
1253253f11b8SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1254253f11b8SEd Tanous     const std::string& managerId)
12557e860f15SJohn Edward Broadbent {
12563ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
125745ca1b86SEd Tanous     {
125845ca1b86SEd Tanous         return;
125945ca1b86SEd Tanous     }
1260253f11b8SEd Tanous 
1261253f11b8SEd Tanous     if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1262253f11b8SEd Tanous     {
1263253f11b8SEd Tanous         messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1264253f11b8SEd Tanous         return;
1265253f11b8SEd Tanous     }
1266253f11b8SEd Tanous 
1267fdd26906SClaire Weinan     getDumpServiceInfo(asyncResp, dumpType);
1268fdd26906SClaire Weinan }
1269c9bb6861Sraviteja-b 
127022d268cbSEd Tanous inline void handleLogServicesDumpServiceComputerSystemGet(
127122d268cbSEd Tanous     crow::App& app, const crow::Request& req,
127222d268cbSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
127322d268cbSEd Tanous     const std::string& chassisId)
127422d268cbSEd Tanous {
127522d268cbSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
127622d268cbSEd Tanous     {
127722d268cbSEd Tanous         return;
127822d268cbSEd Tanous     }
1279253f11b8SEd Tanous     if (chassisId != BMCWEB_REDFISH_SYSTEM_URI_NAME)
128022d268cbSEd Tanous     {
128122d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem", chassisId);
128222d268cbSEd Tanous         return;
128322d268cbSEd Tanous     }
128422d268cbSEd Tanous     getDumpServiceInfo(asyncResp, "System");
128522d268cbSEd Tanous }
128622d268cbSEd Tanous 
1287fdd26906SClaire Weinan inline void handleLogServicesDumpEntriesCollectionGet(
1288fdd26906SClaire Weinan     crow::App& app, const std::string& dumpType, const crow::Request& req,
1289253f11b8SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1290253f11b8SEd Tanous     const std::string& managerId)
1291fdd26906SClaire Weinan {
1292fdd26906SClaire Weinan     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1293fdd26906SClaire Weinan     {
1294fdd26906SClaire Weinan         return;
1295fdd26906SClaire Weinan     }
1296253f11b8SEd Tanous 
1297253f11b8SEd Tanous     if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1298253f11b8SEd Tanous     {
1299253f11b8SEd Tanous         messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1300253f11b8SEd Tanous         return;
1301253f11b8SEd Tanous     }
1302fdd26906SClaire Weinan     getDumpEntryCollection(asyncResp, dumpType);
1303fdd26906SClaire Weinan }
1304fdd26906SClaire Weinan 
130522d268cbSEd Tanous inline void handleLogServicesDumpEntriesCollectionComputerSystemGet(
130622d268cbSEd Tanous     crow::App& app, const crow::Request& req,
130722d268cbSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
130822d268cbSEd Tanous     const std::string& chassisId)
130922d268cbSEd Tanous {
131022d268cbSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
131122d268cbSEd Tanous     {
131222d268cbSEd Tanous         return;
131322d268cbSEd Tanous     }
1314253f11b8SEd Tanous     if (chassisId != BMCWEB_REDFISH_SYSTEM_URI_NAME)
131522d268cbSEd Tanous     {
131622d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem", chassisId);
131722d268cbSEd Tanous         return;
131822d268cbSEd Tanous     }
131922d268cbSEd Tanous     getDumpEntryCollection(asyncResp, "System");
132022d268cbSEd Tanous }
132122d268cbSEd Tanous 
1322fdd26906SClaire Weinan inline void handleLogServicesDumpEntryGet(
1323fdd26906SClaire Weinan     crow::App& app, const std::string& dumpType, const crow::Request& req,
1324fdd26906SClaire Weinan     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1325253f11b8SEd Tanous     const std::string& managerId, const std::string& dumpId)
1326fdd26906SClaire Weinan {
1327fdd26906SClaire Weinan     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1328fdd26906SClaire Weinan     {
1329fdd26906SClaire Weinan         return;
1330fdd26906SClaire Weinan     }
1331253f11b8SEd Tanous     if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1332253f11b8SEd Tanous     {
1333253f11b8SEd Tanous         messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1334253f11b8SEd Tanous         return;
1335253f11b8SEd Tanous     }
1336fdd26906SClaire Weinan     getDumpEntryById(asyncResp, dumpId, dumpType);
1337fdd26906SClaire Weinan }
1338168d1b1aSCarson Labrado 
133922d268cbSEd Tanous inline void handleLogServicesDumpEntryComputerSystemGet(
134022d268cbSEd Tanous     crow::App& app, const crow::Request& req,
134122d268cbSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
134222d268cbSEd Tanous     const std::string& chassisId, const std::string& dumpId)
134322d268cbSEd Tanous {
134422d268cbSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
134522d268cbSEd Tanous     {
134622d268cbSEd Tanous         return;
134722d268cbSEd Tanous     }
1348253f11b8SEd Tanous     if (chassisId != BMCWEB_REDFISH_SYSTEM_URI_NAME)
134922d268cbSEd Tanous     {
135022d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem", chassisId);
135122d268cbSEd Tanous         return;
135222d268cbSEd Tanous     }
135322d268cbSEd Tanous     getDumpEntryById(asyncResp, dumpId, "System");
135422d268cbSEd Tanous }
1355fdd26906SClaire Weinan 
1356fdd26906SClaire Weinan inline void handleLogServicesDumpEntryDelete(
1357fdd26906SClaire Weinan     crow::App& app, const std::string& dumpType, const crow::Request& req,
1358fdd26906SClaire Weinan     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1359253f11b8SEd Tanous     const std::string& managerId, const std::string& dumpId)
1360fdd26906SClaire Weinan {
1361fdd26906SClaire Weinan     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1362fdd26906SClaire Weinan     {
1363fdd26906SClaire Weinan         return;
1364fdd26906SClaire Weinan     }
1365253f11b8SEd Tanous 
1366253f11b8SEd Tanous     if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1367253f11b8SEd Tanous     {
1368253f11b8SEd Tanous         messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1369253f11b8SEd Tanous         return;
1370253f11b8SEd Tanous     }
1371fdd26906SClaire Weinan     deleteDumpEntry(asyncResp, dumpId, dumpType);
1372fdd26906SClaire Weinan }
1373fdd26906SClaire Weinan 
137422d268cbSEd Tanous inline void handleLogServicesDumpEntryComputerSystemDelete(
137522d268cbSEd Tanous     crow::App& app, const crow::Request& req,
137622d268cbSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
137722d268cbSEd Tanous     const std::string& chassisId, const std::string& dumpId)
137822d268cbSEd Tanous {
137922d268cbSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
138022d268cbSEd Tanous     {
138122d268cbSEd Tanous         return;
138222d268cbSEd Tanous     }
1383253f11b8SEd Tanous     if (chassisId != BMCWEB_REDFISH_SYSTEM_URI_NAME)
138422d268cbSEd Tanous     {
138522d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem", chassisId);
138622d268cbSEd Tanous         return;
138722d268cbSEd Tanous     }
138822d268cbSEd Tanous     deleteDumpEntry(asyncResp, dumpId, "System");
138922d268cbSEd Tanous }
139022d268cbSEd Tanous 
1391168d1b1aSCarson Labrado inline void handleLogServicesDumpEntryDownloadGet(
1392168d1b1aSCarson Labrado     crow::App& app, const std::string& dumpType, const crow::Request& req,
1393168d1b1aSCarson Labrado     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1394253f11b8SEd Tanous     const std::string& managerId, const std::string& dumpId)
1395168d1b1aSCarson Labrado {
1396168d1b1aSCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1397168d1b1aSCarson Labrado     {
1398168d1b1aSCarson Labrado         return;
1399168d1b1aSCarson Labrado     }
1400253f11b8SEd Tanous 
1401253f11b8SEd Tanous     if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1402253f11b8SEd Tanous     {
1403253f11b8SEd Tanous         messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1404253f11b8SEd Tanous         return;
1405253f11b8SEd Tanous     }
1406168d1b1aSCarson Labrado     downloadDumpEntry(asyncResp, dumpId, dumpType);
1407168d1b1aSCarson Labrado }
1408168d1b1aSCarson Labrado 
1409fdd26906SClaire Weinan inline void handleLogServicesDumpCollectDiagnosticDataPost(
1410fdd26906SClaire Weinan     crow::App& app, const std::string& dumpType, const crow::Request& req,
1411253f11b8SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1412253f11b8SEd Tanous     const std::string& managerId)
1413fdd26906SClaire Weinan {
1414fdd26906SClaire Weinan     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1415fdd26906SClaire Weinan     {
1416fdd26906SClaire Weinan         return;
1417fdd26906SClaire Weinan     }
1418253f11b8SEd Tanous     if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1419253f11b8SEd Tanous     {
1420253f11b8SEd Tanous         messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1421253f11b8SEd Tanous         return;
1422253f11b8SEd Tanous     }
1423253f11b8SEd Tanous 
1424fdd26906SClaire Weinan     createDump(asyncResp, req, dumpType);
1425fdd26906SClaire Weinan }
1426fdd26906SClaire Weinan 
142722d268cbSEd Tanous inline void handleLogServicesDumpCollectDiagnosticDataComputerSystemPost(
142822d268cbSEd Tanous     crow::App& app, const crow::Request& req,
142922d268cbSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
14307f3e84a1SEd Tanous     const std::string& systemName)
143122d268cbSEd Tanous {
143222d268cbSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
143322d268cbSEd Tanous     {
143422d268cbSEd Tanous         return;
143522d268cbSEd Tanous     }
14367f3e84a1SEd Tanous 
143725b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
143822d268cbSEd Tanous     {
14397f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
14407f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
14417f3e84a1SEd Tanous                                    systemName);
14427f3e84a1SEd Tanous         return;
14437f3e84a1SEd Tanous     }
1444253f11b8SEd Tanous     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
14457f3e84a1SEd Tanous     {
14467f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
14477f3e84a1SEd Tanous                                    systemName);
144822d268cbSEd Tanous         return;
144922d268cbSEd Tanous     }
145022d268cbSEd Tanous     createDump(asyncResp, req, "System");
145122d268cbSEd Tanous }
145222d268cbSEd Tanous 
1453fdd26906SClaire Weinan inline void handleLogServicesDumpClearLogPost(
1454fdd26906SClaire Weinan     crow::App& app, const std::string& dumpType, const crow::Request& req,
1455253f11b8SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1456253f11b8SEd Tanous     const std::string& managerId)
1457fdd26906SClaire Weinan {
1458fdd26906SClaire Weinan     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1459fdd26906SClaire Weinan     {
1460fdd26906SClaire Weinan         return;
1461fdd26906SClaire Weinan     }
1462253f11b8SEd Tanous 
1463253f11b8SEd Tanous     if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1464253f11b8SEd Tanous     {
1465253f11b8SEd Tanous         messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1466253f11b8SEd Tanous         return;
1467253f11b8SEd Tanous     }
1468fdd26906SClaire Weinan     clearDump(asyncResp, dumpType);
1469fdd26906SClaire Weinan }
1470fdd26906SClaire Weinan 
147122d268cbSEd Tanous inline void handleLogServicesDumpClearLogComputerSystemPost(
147222d268cbSEd Tanous     crow::App& app, const crow::Request& req,
147322d268cbSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
14747f3e84a1SEd Tanous     const std::string& systemName)
147522d268cbSEd Tanous {
147622d268cbSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
147722d268cbSEd Tanous     {
147822d268cbSEd Tanous         return;
147922d268cbSEd Tanous     }
148025b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
148122d268cbSEd Tanous     {
14827f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
14837f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
14847f3e84a1SEd Tanous                                    systemName);
14857f3e84a1SEd Tanous         return;
14867f3e84a1SEd Tanous     }
1487253f11b8SEd Tanous     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
14887f3e84a1SEd Tanous     {
14897f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
14907f3e84a1SEd Tanous                                    systemName);
149122d268cbSEd Tanous         return;
149222d268cbSEd Tanous     }
149322d268cbSEd Tanous     clearDump(asyncResp, "System");
149422d268cbSEd Tanous }
149522d268cbSEd Tanous 
1496fdd26906SClaire Weinan inline void requestRoutesBMCDumpService(App& app)
1497fdd26906SClaire Weinan {
1498253f11b8SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/LogServices/Dump/")
1499fdd26906SClaire Weinan         .privileges(redfish::privileges::getLogService)
1500fdd26906SClaire Weinan         .methods(boost::beast::http::verb::get)(std::bind_front(
1501fdd26906SClaire Weinan             handleLogServicesDumpServiceGet, std::ref(app), "BMC"));
1502fdd26906SClaire Weinan }
1503fdd26906SClaire Weinan 
1504fdd26906SClaire Weinan inline void requestRoutesBMCDumpEntryCollection(App& app)
1505fdd26906SClaire Weinan {
1506253f11b8SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/LogServices/Dump/Entries/")
1507fdd26906SClaire Weinan         .privileges(redfish::privileges::getLogEntryCollection)
1508fdd26906SClaire Weinan         .methods(boost::beast::http::verb::get)(std::bind_front(
1509fdd26906SClaire Weinan             handleLogServicesDumpEntriesCollectionGet, std::ref(app), "BMC"));
1510c9bb6861Sraviteja-b }
1511c9bb6861Sraviteja-b 
15127e860f15SJohn Edward Broadbent inline void requestRoutesBMCDumpEntry(App& app)
1513c9bb6861Sraviteja-b {
15147e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app,
1515253f11b8SEd Tanous                  "/redfish/v1/Managers/<str>/LogServices/Dump/Entries/<str>/")
1516ed398213SEd Tanous         .privileges(redfish::privileges::getLogEntry)
1517fdd26906SClaire Weinan         .methods(boost::beast::http::verb::get)(std::bind_front(
1518fdd26906SClaire Weinan             handleLogServicesDumpEntryGet, std::ref(app), "BMC"));
1519fdd26906SClaire Weinan 
15207e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app,
1521253f11b8SEd Tanous                  "/redfish/v1/Managers/<str>/LogServices/Dump/Entries/<str>/")
1522ed398213SEd Tanous         .privileges(redfish::privileges::deleteLogEntry)
1523fdd26906SClaire Weinan         .methods(boost::beast::http::verb::delete_)(std::bind_front(
1524fdd26906SClaire Weinan             handleLogServicesDumpEntryDelete, std::ref(app), "BMC"));
1525c9bb6861Sraviteja-b }
1526c9bb6861Sraviteja-b 
1527168d1b1aSCarson Labrado inline void requestRoutesBMCDumpEntryDownload(App& app)
1528168d1b1aSCarson Labrado {
1529168d1b1aSCarson Labrado     BMCWEB_ROUTE(
1530168d1b1aSCarson Labrado         app,
1531253f11b8SEd Tanous         "/redfish/v1/Managers/<str>/LogServices/Dump/Entries/<str>/attachment/")
1532168d1b1aSCarson Labrado         .privileges(redfish::privileges::getLogEntry)
1533168d1b1aSCarson Labrado         .methods(boost::beast::http::verb::get)(std::bind_front(
1534168d1b1aSCarson Labrado             handleLogServicesDumpEntryDownloadGet, std::ref(app), "BMC"));
1535168d1b1aSCarson Labrado }
1536168d1b1aSCarson Labrado 
15377e860f15SJohn Edward Broadbent inline void requestRoutesBMCDumpCreate(App& app)
1538c9bb6861Sraviteja-b {
15390fda0f12SGeorge Liu     BMCWEB_ROUTE(
15400fda0f12SGeorge Liu         app,
1541253f11b8SEd Tanous         "/redfish/v1/Managers/<str>/LogServices/Dump/Actions/LogService.CollectDiagnosticData/")
1542ed398213SEd Tanous         .privileges(redfish::privileges::postLogService)
15437e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::post)(
1544fdd26906SClaire Weinan             std::bind_front(handleLogServicesDumpCollectDiagnosticDataPost,
1545fdd26906SClaire Weinan                             std::ref(app), "BMC"));
1546a43be80fSAsmitha Karunanithi }
1547a43be80fSAsmitha Karunanithi 
15487e860f15SJohn Edward Broadbent inline void requestRoutesBMCDumpClear(App& app)
154980319af1SAsmitha Karunanithi {
15500fda0f12SGeorge Liu     BMCWEB_ROUTE(
15510fda0f12SGeorge Liu         app,
1552253f11b8SEd Tanous         "/redfish/v1/Managers/<str>/LogServices/Dump/Actions/LogService.ClearLog/")
1553ed398213SEd Tanous         .privileges(redfish::privileges::postLogService)
1554fdd26906SClaire Weinan         .methods(boost::beast::http::verb::post)(std::bind_front(
1555fdd26906SClaire Weinan             handleLogServicesDumpClearLogPost, std::ref(app), "BMC"));
155645ca1b86SEd Tanous }
1557fdd26906SClaire Weinan 
1558fdd26906SClaire Weinan inline void requestRoutesFaultLogDumpService(App& app)
1559fdd26906SClaire Weinan {
1560253f11b8SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/LogServices/FaultLog/")
1561fdd26906SClaire Weinan         .privileges(redfish::privileges::getLogService)
1562fdd26906SClaire Weinan         .methods(boost::beast::http::verb::get)(std::bind_front(
1563fdd26906SClaire Weinan             handleLogServicesDumpServiceGet, std::ref(app), "FaultLog"));
1564fdd26906SClaire Weinan }
1565fdd26906SClaire Weinan 
1566fdd26906SClaire Weinan inline void requestRoutesFaultLogDumpEntryCollection(App& app)
1567fdd26906SClaire Weinan {
1568253f11b8SEd Tanous     BMCWEB_ROUTE(app,
1569253f11b8SEd Tanous                  "/redfish/v1/Managers/<str>/LogServices/FaultLog/Entries/")
1570fdd26906SClaire Weinan         .privileges(redfish::privileges::getLogEntryCollection)
1571fdd26906SClaire Weinan         .methods(boost::beast::http::verb::get)(
1572fdd26906SClaire Weinan             std::bind_front(handleLogServicesDumpEntriesCollectionGet,
1573fdd26906SClaire Weinan                             std::ref(app), "FaultLog"));
1574fdd26906SClaire Weinan }
1575fdd26906SClaire Weinan 
1576fdd26906SClaire Weinan inline void requestRoutesFaultLogDumpEntry(App& app)
1577fdd26906SClaire Weinan {
1578253f11b8SEd Tanous     BMCWEB_ROUTE(
1579253f11b8SEd Tanous         app, "/redfish/v1/Managers/<str>/LogServices/FaultLog/Entries/<str>/")
1580fdd26906SClaire Weinan         .privileges(redfish::privileges::getLogEntry)
1581fdd26906SClaire Weinan         .methods(boost::beast::http::verb::get)(std::bind_front(
1582fdd26906SClaire Weinan             handleLogServicesDumpEntryGet, std::ref(app), "FaultLog"));
1583fdd26906SClaire Weinan 
1584253f11b8SEd Tanous     BMCWEB_ROUTE(
1585253f11b8SEd Tanous         app, "/redfish/v1/Managers/<str>/LogServices/FaultLog/Entries/<str>/")
1586fdd26906SClaire Weinan         .privileges(redfish::privileges::deleteLogEntry)
1587fdd26906SClaire Weinan         .methods(boost::beast::http::verb::delete_)(std::bind_front(
1588fdd26906SClaire Weinan             handleLogServicesDumpEntryDelete, std::ref(app), "FaultLog"));
1589fdd26906SClaire Weinan }
1590fdd26906SClaire Weinan 
1591fdd26906SClaire Weinan inline void requestRoutesFaultLogDumpClear(App& app)
1592fdd26906SClaire Weinan {
1593fdd26906SClaire Weinan     BMCWEB_ROUTE(
1594fdd26906SClaire Weinan         app,
1595253f11b8SEd Tanous         "/redfish/v1/Managers/<str>/LogServices/FaultLog/Actions/LogService.ClearLog/")
1596fdd26906SClaire Weinan         .privileges(redfish::privileges::postLogService)
1597fdd26906SClaire Weinan         .methods(boost::beast::http::verb::post)(std::bind_front(
1598fdd26906SClaire Weinan             handleLogServicesDumpClearLogPost, std::ref(app), "FaultLog"));
15995cb1dd27SAsmitha Karunanithi }
16005cb1dd27SAsmitha Karunanithi 
16017e860f15SJohn Edward Broadbent inline void requestRoutesSystemDumpService(App& app)
16025cb1dd27SAsmitha Karunanithi {
160322d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/Dump/")
1604ed398213SEd Tanous         .privileges(redfish::privileges::getLogService)
16056ab9ad54SClaire Weinan         .methods(boost::beast::http::verb::get)(std::bind_front(
160622d268cbSEd Tanous             handleLogServicesDumpServiceComputerSystemGet, std::ref(app)));
16075cb1dd27SAsmitha Karunanithi }
16085cb1dd27SAsmitha Karunanithi 
16097e860f15SJohn Edward Broadbent inline void requestRoutesSystemDumpEntryCollection(App& app)
16107e860f15SJohn Edward Broadbent {
161122d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/Dump/Entries/")
1612ed398213SEd Tanous         .privileges(redfish::privileges::getLogEntryCollection)
161322d268cbSEd Tanous         .methods(boost::beast::http::verb::get)(std::bind_front(
161422d268cbSEd Tanous             handleLogServicesDumpEntriesCollectionComputerSystemGet,
161522d268cbSEd Tanous             std::ref(app)));
16165cb1dd27SAsmitha Karunanithi }
16175cb1dd27SAsmitha Karunanithi 
16187e860f15SJohn Edward Broadbent inline void requestRoutesSystemDumpEntry(App& app)
16195cb1dd27SAsmitha Karunanithi {
16207e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app,
162122d268cbSEd Tanous                  "/redfish/v1/Systems/<str>/LogServices/Dump/Entries/<str>/")
1622ed398213SEd Tanous         .privileges(redfish::privileges::getLogEntry)
16236ab9ad54SClaire Weinan         .methods(boost::beast::http::verb::get)(std::bind_front(
162422d268cbSEd Tanous             handleLogServicesDumpEntryComputerSystemGet, std::ref(app)));
16258d1b46d7Szhanghch05 
16267e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app,
162722d268cbSEd Tanous                  "/redfish/v1/Systems/<str>/LogServices/Dump/Entries/<str>/")
1628ed398213SEd Tanous         .privileges(redfish::privileges::deleteLogEntry)
16296ab9ad54SClaire Weinan         .methods(boost::beast::http::verb::delete_)(std::bind_front(
163022d268cbSEd Tanous             handleLogServicesDumpEntryComputerSystemDelete, std::ref(app)));
16315cb1dd27SAsmitha Karunanithi }
1632c9bb6861Sraviteja-b 
16337e860f15SJohn Edward Broadbent inline void requestRoutesSystemDumpCreate(App& app)
1634c9bb6861Sraviteja-b {
16350fda0f12SGeorge Liu     BMCWEB_ROUTE(
16360fda0f12SGeorge Liu         app,
163722d268cbSEd Tanous         "/redfish/v1/Systems/<str>/LogServices/Dump/Actions/LogService.CollectDiagnosticData/")
1638fff6a4d3SAbhishek Patel         .privileges(redfish::privileges::
1639fff6a4d3SAbhishek Patel                         postLogServiceSubOverComputerSystemLogServiceCollection)
164022d268cbSEd Tanous         .methods(boost::beast::http::verb::post)(std::bind_front(
164122d268cbSEd Tanous             handleLogServicesDumpCollectDiagnosticDataComputerSystemPost,
164222d268cbSEd Tanous             std::ref(app)));
1643a43be80fSAsmitha Karunanithi }
1644a43be80fSAsmitha Karunanithi 
16457e860f15SJohn Edward Broadbent inline void requestRoutesSystemDumpClear(App& app)
1646a43be80fSAsmitha Karunanithi {
16470fda0f12SGeorge Liu     BMCWEB_ROUTE(
16480fda0f12SGeorge Liu         app,
164922d268cbSEd Tanous         "/redfish/v1/Systems/<str>/LogServices/Dump/Actions/LogService.ClearLog/")
1650fff6a4d3SAbhishek Patel         .privileges(redfish::privileges::
1651fff6a4d3SAbhishek Patel                         postLogServiceSubOverComputerSystemLogServiceCollection)
16526ab9ad54SClaire Weinan         .methods(boost::beast::http::verb::post)(std::bind_front(
165322d268cbSEd Tanous             handleLogServicesDumpClearLogComputerSystemPost, std::ref(app)));
1654013487e5Sraviteja-b }
1655013487e5Sraviteja-b 
16567e860f15SJohn Edward Broadbent inline void requestRoutesCrashdumpService(App& app)
16571da66f75SEd Tanous {
16581da66f75SEd Tanous     /**
16591da66f75SEd Tanous      * Functions triggers appropriate requests on DBus
16601da66f75SEd Tanous      */
166122d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/Crashdump/")
166250d9f38aSMyung Bae         .privileges(redfish::privileges::getLogService)
1663bd79bce8SPatrick Williams         .methods(
1664bd79bce8SPatrick Williams             boost::beast::http::verb::
1665bd79bce8SPatrick Williams                 get)([&app](const crow::Request& req,
166622d268cbSEd Tanous                             const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
166722d268cbSEd Tanous                             const std::string& systemName) {
16683ba00073SCarson Labrado             if (!redfish::setUpRedfishRoute(app, req, asyncResp))
166945ca1b86SEd Tanous             {
167045ca1b86SEd Tanous                 return;
167145ca1b86SEd Tanous             }
167225b54dbaSEd Tanous             if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
16737f3e84a1SEd Tanous             {
16747f3e84a1SEd Tanous                 // Option currently returns no systems.  TBD
16757f3e84a1SEd Tanous                 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
16767f3e84a1SEd Tanous                                            systemName);
16777f3e84a1SEd Tanous                 return;
16787f3e84a1SEd Tanous             }
1679253f11b8SEd Tanous             if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
168022d268cbSEd Tanous             {
168122d268cbSEd Tanous                 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
168222d268cbSEd Tanous                                            systemName);
168322d268cbSEd Tanous                 return;
168422d268cbSEd Tanous             }
168522d268cbSEd Tanous 
16867e860f15SJohn Edward Broadbent             // Copy over the static data to include the entries added by
16877e860f15SJohn Edward Broadbent             // SubRoute
16880f74e643SEd Tanous             asyncResp->res.jsonValue["@odata.id"] =
1689253f11b8SEd Tanous                 std::format("/redfish/v1/Systems/{}/LogServices/Crashdump",
1690253f11b8SEd Tanous                             BMCWEB_REDFISH_SYSTEM_URI_NAME);
1691e1f26343SJason M. Bills             asyncResp->res.jsonValue["@odata.type"] =
16928e6c099aSJason M. Bills                 "#LogService.v1_2_0.LogService";
16934f50ae4bSGunnar Mills             asyncResp->res.jsonValue["Name"] = "Open BMC Oem Crashdump Service";
16944f50ae4bSGunnar Mills             asyncResp->res.jsonValue["Description"] = "Oem Crashdump Service";
169515b89725SV-Sanjana             asyncResp->res.jsonValue["Id"] = "Crashdump";
1696539d8c6bSEd Tanous             asyncResp->res.jsonValue["OverWritePolicy"] =
1697539d8c6bSEd Tanous                 log_service::OverWritePolicy::WrapsWhenFull;
1698e1f26343SJason M. Bills             asyncResp->res.jsonValue["MaxNumberOfRecords"] = 3;
16997c8c4058STejas Patil 
17007c8c4058STejas Patil             std::pair<std::string, std::string> redfishDateTimeOffset =
17012b82937eSEd Tanous                 redfish::time_utils::getDateTimeOffsetNow();
17027c8c4058STejas Patil             asyncResp->res.jsonValue["DateTime"] = redfishDateTimeOffset.first;
17037c8c4058STejas Patil             asyncResp->res.jsonValue["DateTimeLocalOffset"] =
17047c8c4058STejas Patil                 redfishDateTimeOffset.second;
17057c8c4058STejas Patil 
1706bd79bce8SPatrick Williams             asyncResp->res.jsonValue["Entries"]["@odata.id"] = std::format(
1707bd79bce8SPatrick Williams                 "/redfish/v1/Systems/{}/LogServices/Crashdump/Entries",
1708253f11b8SEd Tanous                 BMCWEB_REDFISH_SYSTEM_URI_NAME);
1709253f11b8SEd Tanous             asyncResp->res.jsonValue["Actions"]["#LogService.ClearLog"]
1710253f11b8SEd Tanous                                     ["target"] = std::format(
1711253f11b8SEd Tanous                 "/redfish/v1/Systems/{}/LogServices/Crashdump/Actions/LogService.ClearLog",
1712253f11b8SEd Tanous                 BMCWEB_REDFISH_SYSTEM_URI_NAME);
1713bd79bce8SPatrick Williams             asyncResp->res
1714bd79bce8SPatrick Williams                 .jsonValue["Actions"]["#LogService.CollectDiagnosticData"]
1715253f11b8SEd Tanous                           ["target"] = std::format(
1716253f11b8SEd Tanous                 "/redfish/v1/Systems/{}/LogServices/Crashdump/Actions/LogService.CollectDiagnosticData",
1717253f11b8SEd Tanous                 BMCWEB_REDFISH_SYSTEM_URI_NAME);
1718*08fad5d9SCorey Ethington 
1719*08fad5d9SCorey Ethington             etag_utils::setEtagOmitDateTimeHandler(asyncResp);
17207e860f15SJohn Edward Broadbent         });
17211da66f75SEd Tanous }
17221da66f75SEd Tanous 
17238e4736b3SEd Tanous inline void requestRoutesCrashdumpClear(App& app)
17245b61b5e8SJason M. Bills {
17250fda0f12SGeorge Liu     BMCWEB_ROUTE(
17260fda0f12SGeorge Liu         app,
172722d268cbSEd Tanous         "/redfish/v1/Systems/<str>/LogServices/Crashdump/Actions/LogService.ClearLog/")
172850d9f38aSMyung Bae         .privileges(redfish::privileges::
172950d9f38aSMyung Bae                         postLogServiceSubOverComputerSystemLogServiceCollection)
17307e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::post)(
173145ca1b86SEd Tanous             [&app](const crow::Request& req,
173222d268cbSEd Tanous                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
173322d268cbSEd Tanous                    const std::string& systemName) {
17343ba00073SCarson Labrado                 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
173545ca1b86SEd Tanous                 {
173645ca1b86SEd Tanous                     return;
173745ca1b86SEd Tanous                 }
173825b54dbaSEd Tanous                 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
17397f3e84a1SEd Tanous                 {
17407f3e84a1SEd Tanous                     // Option currently returns no systems.  TBD
17417f3e84a1SEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
17427f3e84a1SEd Tanous                                                systemName);
17437f3e84a1SEd Tanous                     return;
17447f3e84a1SEd Tanous                 }
1745253f11b8SEd Tanous                 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
174622d268cbSEd Tanous                 {
174722d268cbSEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
174822d268cbSEd Tanous                                                systemName);
174922d268cbSEd Tanous                     return;
175022d268cbSEd Tanous                 }
1751177612aaSEd Tanous                 dbus::utility::async_method_call(
1752177612aaSEd Tanous                     asyncResp,
17535e7e2dc5SEd Tanous                     [asyncResp](const boost::system::error_code& ec,
1754cb13a392SEd Tanous                                 const std::string&) {
17555b61b5e8SJason M. Bills                         if (ec)
17565b61b5e8SJason M. Bills                         {
17575b61b5e8SJason M. Bills                             messages::internalError(asyncResp->res);
17585b61b5e8SJason M. Bills                             return;
17595b61b5e8SJason M. Bills                         }
17605b61b5e8SJason M. Bills                         messages::success(asyncResp->res);
17615b61b5e8SJason M. Bills                     },
1762bd79bce8SPatrick Williams                     crashdumpObject, crashdumpPath, deleteAllInterface,
1763bd79bce8SPatrick Williams                     "DeleteAll");
17647e860f15SJohn Edward Broadbent             });
17655b61b5e8SJason M. Bills }
17665b61b5e8SJason M. Bills 
1767504af5a0SPatrick Williams inline void logCrashdumpEntry(
1768504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
17698d1b46d7Szhanghch05     const std::string& logID, nlohmann::json& logEntryJson)
1770e855dd28SJason M. Bills {
1771043a0536SJohnathan Mantey     auto getStoredLogCallback =
1772b9d36b47SEd Tanous         [asyncResp, logID,
17735e7e2dc5SEd Tanous          &logEntryJson](const boost::system::error_code& ec,
1774b9d36b47SEd Tanous                         const dbus::utility::DBusPropertiesMap& params) {
1775e855dd28SJason M. Bills             if (ec)
1776e855dd28SJason M. Bills             {
177762598e31SEd Tanous                 BMCWEB_LOG_DEBUG("failed to get log ec: {}", ec.message());
17781ddcf01aSJason M. Bills                 if (ec.value() ==
17791ddcf01aSJason M. Bills                     boost::system::linux_error::bad_request_descriptor)
17801ddcf01aSJason M. Bills                 {
1781bd79bce8SPatrick Williams                     messages::resourceNotFound(asyncResp->res, "LogEntry",
1782bd79bce8SPatrick Williams                                                logID);
17831ddcf01aSJason M. Bills                 }
17841ddcf01aSJason M. Bills                 else
17851ddcf01aSJason M. Bills                 {
1786e855dd28SJason M. Bills                     messages::internalError(asyncResp->res);
17871ddcf01aSJason M. Bills                 }
1788e855dd28SJason M. Bills                 return;
1789e855dd28SJason M. Bills             }
1790043a0536SJohnathan Mantey 
1791043a0536SJohnathan Mantey             std::string timestamp{};
1792043a0536SJohnathan Mantey             std::string filename{};
1793043a0536SJohnathan Mantey             std::string logfile{};
17942c70f800SEd Tanous             parseCrashdumpParameters(params, filename, timestamp, logfile);
1795043a0536SJohnathan Mantey 
1796043a0536SJohnathan Mantey             if (filename.empty() || timestamp.empty())
1797e855dd28SJason M. Bills             {
17989db4ba25SJiaqing Zhao                 messages::resourceNotFound(asyncResp->res, "LogEntry", logID);
1799e855dd28SJason M. Bills                 return;
1800e855dd28SJason M. Bills             }
1801e855dd28SJason M. Bills 
1802043a0536SJohnathan Mantey             std::string crashdumpURI =
1803bd79bce8SPatrick Williams                 std::format(
1804bd79bce8SPatrick Williams                     "/redfish/v1/Systems/{}/LogServices/Crashdump/Entries/",
1805253f11b8SEd Tanous                     BMCWEB_REDFISH_SYSTEM_URI_NAME) +
1806043a0536SJohnathan Mantey                 logID + "/" + filename;
180784afc48bSJason M. Bills             nlohmann::json::object_t logEntry;
18089c11a172SVijay Lobo             logEntry["@odata.type"] = "#LogEntry.v1_9_0.LogEntry";
1809ef4c65b7SEd Tanous             logEntry["@odata.id"] = boost::urls::format(
1810253f11b8SEd Tanous                 "/redfish/v1/Systems/{}/LogServices/Crashdump/Entries/{}",
1811253f11b8SEd Tanous                 BMCWEB_REDFISH_SYSTEM_URI_NAME, logID);
181284afc48bSJason M. Bills             logEntry["Name"] = "CPU Crashdump";
181384afc48bSJason M. Bills             logEntry["Id"] = logID;
1814539d8c6bSEd Tanous             logEntry["EntryType"] = log_entry::LogEntryType::Oem;
181584afc48bSJason M. Bills             logEntry["AdditionalDataURI"] = std::move(crashdumpURI);
181684afc48bSJason M. Bills             logEntry["DiagnosticDataType"] = "OEM";
181784afc48bSJason M. Bills             logEntry["OEMDiagnosticDataType"] = "PECICrashdump";
181884afc48bSJason M. Bills             logEntry["Created"] = std::move(timestamp);
18192b20ef6eSJason M. Bills 
18202b20ef6eSJason M. Bills             // If logEntryJson references an array of LogEntry resources
18212b20ef6eSJason M. Bills             // ('Members' list), then push this as a new entry, otherwise set it
18222b20ef6eSJason M. Bills             // directly
18232b20ef6eSJason M. Bills             if (logEntryJson.is_array())
18242b20ef6eSJason M. Bills             {
18252b20ef6eSJason M. Bills                 logEntryJson.push_back(logEntry);
18262b20ef6eSJason M. Bills                 asyncResp->res.jsonValue["Members@odata.count"] =
18272b20ef6eSJason M. Bills                     logEntryJson.size();
18282b20ef6eSJason M. Bills             }
18292b20ef6eSJason M. Bills             else
18302b20ef6eSJason M. Bills             {
1831d405bb51SJason M. Bills                 logEntryJson.update(logEntry);
18322b20ef6eSJason M. Bills             }
1833e855dd28SJason M. Bills         };
1834deae6a78SEd Tanous     dbus::utility::getAllProperties(
1835deae6a78SEd Tanous         crashdumpObject, crashdumpPath + std::string("/") + logID,
1836deae6a78SEd Tanous         crashdumpInterface, std::move(getStoredLogCallback));
1837e855dd28SJason M. Bills }
1838e855dd28SJason M. Bills 
18397e860f15SJohn Edward Broadbent inline void requestRoutesCrashdumpEntryCollection(App& app)
18401da66f75SEd Tanous {
18411da66f75SEd Tanous     /**
18421da66f75SEd Tanous      * Functions triggers appropriate requests on DBus
18431da66f75SEd Tanous      */
18447e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app,
184522d268cbSEd Tanous                  "/redfish/v1/Systems/<str>/LogServices/Crashdump/Entries/")
184650d9f38aSMyung Bae         .privileges(redfish::privileges::getLogEntryCollection)
1847bd79bce8SPatrick Williams         .methods(
1848bd79bce8SPatrick Williams             boost::beast::http::verb::
1849bd79bce8SPatrick Williams                 get)([&app](const crow::Request& req,
185022d268cbSEd Tanous                             const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
185122d268cbSEd Tanous                             const std::string& systemName) {
18523ba00073SCarson Labrado             if (!redfish::setUpRedfishRoute(app, req, asyncResp))
185345ca1b86SEd Tanous             {
185445ca1b86SEd Tanous                 return;
185545ca1b86SEd Tanous             }
185625b54dbaSEd Tanous             if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
18577f3e84a1SEd Tanous             {
18587f3e84a1SEd Tanous                 // Option currently returns no systems.  TBD
18597f3e84a1SEd Tanous                 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
18607f3e84a1SEd Tanous                                            systemName);
18617f3e84a1SEd Tanous                 return;
18627f3e84a1SEd Tanous             }
1863253f11b8SEd Tanous             if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
186422d268cbSEd Tanous             {
186522d268cbSEd Tanous                 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
186622d268cbSEd Tanous                                            systemName);
186722d268cbSEd Tanous                 return;
186822d268cbSEd Tanous             }
186922d268cbSEd Tanous 
18707a1dbc48SGeorge Liu             constexpr std::array<std::string_view, 1> interfaces = {
18717a1dbc48SGeorge Liu                 crashdumpInterface};
18727a1dbc48SGeorge Liu             dbus::utility::getSubTreePaths(
18737a1dbc48SGeorge Liu                 "/", 0, interfaces,
18747a1dbc48SGeorge Liu                 [asyncResp](const boost::system::error_code& ec,
18752b20ef6eSJason M. Bills                             const std::vector<std::string>& resp) {
18761da66f75SEd Tanous                     if (ec)
18771da66f75SEd Tanous                     {
18781da66f75SEd Tanous                         if (ec.value() !=
18791da66f75SEd Tanous                             boost::system::errc::no_such_file_or_directory)
18801da66f75SEd Tanous                         {
188162598e31SEd Tanous                             BMCWEB_LOG_DEBUG("failed to get entries ec: {}",
188262598e31SEd Tanous                                              ec.message());
1883f12894f8SJason M. Bills                             messages::internalError(asyncResp->res);
18841da66f75SEd Tanous                             return;
18851da66f75SEd Tanous                         }
18861da66f75SEd Tanous                     }
1887e1f26343SJason M. Bills                     asyncResp->res.jsonValue["@odata.type"] =
18881da66f75SEd Tanous                         "#LogEntryCollection.LogEntryCollection";
1889253f11b8SEd Tanous                     asyncResp->res.jsonValue["@odata.id"] = std::format(
1890253f11b8SEd Tanous                         "/redfish/v1/Systems/{}/LogServices/Crashdump/Entries",
1891253f11b8SEd Tanous                         BMCWEB_REDFISH_SYSTEM_URI_NAME);
1892bd79bce8SPatrick Williams                     asyncResp->res.jsonValue["Name"] =
1893bd79bce8SPatrick Williams                         "Open BMC Crashdump Entries";
1894e1f26343SJason M. Bills                     asyncResp->res.jsonValue["Description"] =
1895424c4176SJason M. Bills                         "Collection of Crashdump Entries";
1896bd79bce8SPatrick Williams                     asyncResp->res.jsonValue["Members"] =
1897bd79bce8SPatrick Williams                         nlohmann::json::array();
1898a2dd60a6SBrandon Kim                     asyncResp->res.jsonValue["Members@odata.count"] = 0;
18992b20ef6eSJason M. Bills 
19002b20ef6eSJason M. Bills                     for (const std::string& path : resp)
19011da66f75SEd Tanous                     {
19022b20ef6eSJason M. Bills                         const sdbusplus::message::object_path objPath(path);
1903e855dd28SJason M. Bills                         // Get the log ID
19042b20ef6eSJason M. Bills                         std::string logID = objPath.filename();
19052b20ef6eSJason M. Bills                         if (logID.empty())
19061da66f75SEd Tanous                         {
1907e855dd28SJason M. Bills                             continue;
19081da66f75SEd Tanous                         }
1909e855dd28SJason M. Bills                         // Add the log entry to the array
19102b20ef6eSJason M. Bills                         logCrashdumpEntry(asyncResp, logID,
19112b20ef6eSJason M. Bills                                           asyncResp->res.jsonValue["Members"]);
19121da66f75SEd Tanous                     }
19137a1dbc48SGeorge Liu                 });
19147e860f15SJohn Edward Broadbent         });
19151da66f75SEd Tanous }
19161da66f75SEd Tanous 
19177e860f15SJohn Edward Broadbent inline void requestRoutesCrashdumpEntry(App& app)
19181da66f75SEd Tanous {
19197e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(
192022d268cbSEd Tanous         app, "/redfish/v1/Systems/<str>/LogServices/Crashdump/Entries/<str>/")
192150d9f38aSMyung Bae         .privileges(redfish::privileges::getLogEntry)
19227e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
192345ca1b86SEd Tanous             [&app](const crow::Request& req,
19247e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
192522d268cbSEd Tanous                    const std::string& systemName, const std::string& param) {
19263ba00073SCarson Labrado                 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
192745ca1b86SEd Tanous                 {
192845ca1b86SEd Tanous                     return;
192945ca1b86SEd Tanous                 }
193025b54dbaSEd Tanous                 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
19317f3e84a1SEd Tanous                 {
19327f3e84a1SEd Tanous                     // Option currently returns no systems.  TBD
19337f3e84a1SEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
19347f3e84a1SEd Tanous                                                systemName);
19357f3e84a1SEd Tanous                     return;
19367f3e84a1SEd Tanous                 }
1937253f11b8SEd Tanous                 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
193822d268cbSEd Tanous                 {
193922d268cbSEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
194022d268cbSEd Tanous                                                systemName);
194122d268cbSEd Tanous                     return;
194222d268cbSEd Tanous                 }
19437e860f15SJohn Edward Broadbent                 const std::string& logID = param;
1944e855dd28SJason M. Bills                 logCrashdumpEntry(asyncResp, logID, asyncResp->res.jsonValue);
19457e860f15SJohn Edward Broadbent             });
1946e855dd28SJason M. Bills }
1947e855dd28SJason M. Bills 
19487e860f15SJohn Edward Broadbent inline void requestRoutesCrashdumpFile(App& app)
1949e855dd28SJason M. Bills {
19507e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(
19517e860f15SJohn Edward Broadbent         app,
195222d268cbSEd Tanous         "/redfish/v1/Systems/<str>/LogServices/Crashdump/Entries/<str>/<str>/")
1953ed398213SEd Tanous         .privileges(redfish::privileges::getLogEntry)
19547e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
1955a4ce114aSNan Zhou             [](const crow::Request& req,
19567e860f15SJohn Edward Broadbent                const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
195722d268cbSEd Tanous                const std::string& systemName, const std::string& logID,
195822d268cbSEd Tanous                const std::string& fileName) {
1959bd79bce8SPatrick Williams                 // Do not call getRedfishRoute here since the crashdump file is
1960bd79bce8SPatrick Williams                 // not a Redfish resource.
196122d268cbSEd Tanous 
196225b54dbaSEd Tanous                 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
19637f3e84a1SEd Tanous                 {
19647f3e84a1SEd Tanous                     // Option currently returns no systems.  TBD
19657f3e84a1SEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
19667f3e84a1SEd Tanous                                                systemName);
19677f3e84a1SEd Tanous                     return;
19687f3e84a1SEd Tanous                 }
1969253f11b8SEd Tanous                 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
197022d268cbSEd Tanous                 {
197122d268cbSEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
197222d268cbSEd Tanous                                                systemName);
197322d268cbSEd Tanous                     return;
197422d268cbSEd Tanous                 }
197522d268cbSEd Tanous 
1976043a0536SJohnathan Mantey                 auto getStoredLogCallback =
1977bd79bce8SPatrick Williams                     [asyncResp, logID, fileName,
1978bd79bce8SPatrick Williams                      url(boost::urls::url(req.url()))](
19795e7e2dc5SEd Tanous                         const boost::system::error_code& ec,
1980bd79bce8SPatrick Williams                         const std::vector<std::pair<
1981bd79bce8SPatrick Williams                             std::string, dbus::utility::DbusVariantType>>&
19827e860f15SJohn Edward Broadbent                             resp) {
19831da66f75SEd Tanous                         if (ec)
19841da66f75SEd Tanous                         {
1985bd79bce8SPatrick Williams                             BMCWEB_LOG_DEBUG("failed to get log ec: {}",
1986bd79bce8SPatrick Williams                                              ec.message());
1987f12894f8SJason M. Bills                             messages::internalError(asyncResp->res);
19881da66f75SEd Tanous                             return;
19891da66f75SEd Tanous                         }
1990e855dd28SJason M. Bills 
1991043a0536SJohnathan Mantey                         std::string dbusFilename{};
1992043a0536SJohnathan Mantey                         std::string dbusTimestamp{};
1993043a0536SJohnathan Mantey                         std::string dbusFilepath{};
1994043a0536SJohnathan Mantey 
1995bd79bce8SPatrick Williams                         parseCrashdumpParameters(resp, dbusFilename,
1996bd79bce8SPatrick Williams                                                  dbusTimestamp, dbusFilepath);
1997043a0536SJohnathan Mantey 
1998043a0536SJohnathan Mantey                         if (dbusFilename.empty() || dbusTimestamp.empty() ||
1999043a0536SJohnathan Mantey                             dbusFilepath.empty())
20001da66f75SEd Tanous                         {
2001bd79bce8SPatrick Williams                             messages::resourceNotFound(asyncResp->res,
2002bd79bce8SPatrick Williams                                                        "LogEntry", logID);
20031da66f75SEd Tanous                             return;
20041da66f75SEd Tanous                         }
2005e855dd28SJason M. Bills 
2006043a0536SJohnathan Mantey                         // Verify the file name parameter is correct
2007043a0536SJohnathan Mantey                         if (fileName != dbusFilename)
2008043a0536SJohnathan Mantey                         {
2009bd79bce8SPatrick Williams                             messages::resourceNotFound(asyncResp->res,
2010bd79bce8SPatrick Williams                                                        "LogEntry", logID);
2011043a0536SJohnathan Mantey                             return;
2012043a0536SJohnathan Mantey                         }
2013043a0536SJohnathan Mantey 
2014d51c61b4SMyung Bae                         if (asyncResp->res.openFile(dbusFilepath) !=
2015d51c61b4SMyung Bae                             crow::OpenCode::Success)
2016043a0536SJohnathan Mantey                         {
2017bd79bce8SPatrick Williams                             messages::resourceNotFound(asyncResp->res,
2018bd79bce8SPatrick Williams                                                        "LogEntry", logID);
2019043a0536SJohnathan Mantey                             return;
2020043a0536SJohnathan Mantey                         }
2021043a0536SJohnathan Mantey 
20227e860f15SJohn Edward Broadbent                         // Configure this to be a file download when accessed
20237e860f15SJohn Edward Broadbent                         // from a browser
2024d9f6c621SEd Tanous                         asyncResp->res.addHeader(
2025bd79bce8SPatrick Williams                             boost::beast::http::field::content_disposition,
2026bd79bce8SPatrick Williams                             "attachment");
20271da66f75SEd Tanous                     };
2028deae6a78SEd Tanous                 dbus::utility::getAllProperties(
2029d1bde9e5SKrzysztof Grobelny                     *crow::connections::systemBus, crashdumpObject,
2030bd79bce8SPatrick Williams                     crashdumpPath + std::string("/") + logID,
2031bd79bce8SPatrick Williams                     crashdumpInterface, std::move(getStoredLogCallback));
20327e860f15SJohn Edward Broadbent             });
20331da66f75SEd Tanous }
20341da66f75SEd Tanous 
2035c5a4c82aSJason M. Bills enum class OEMDiagnosticType
2036c5a4c82aSJason M. Bills {
2037c5a4c82aSJason M. Bills     onDemand,
2038c5a4c82aSJason M. Bills     telemetry,
2039c5a4c82aSJason M. Bills     invalid,
2040c5a4c82aSJason M. Bills };
2041c5a4c82aSJason M. Bills 
204226ccae32SEd Tanous inline OEMDiagnosticType getOEMDiagnosticType(std::string_view oemDiagStr)
2043c5a4c82aSJason M. Bills {
2044c5a4c82aSJason M. Bills     if (oemDiagStr == "OnDemand")
2045c5a4c82aSJason M. Bills     {
2046c5a4c82aSJason M. Bills         return OEMDiagnosticType::onDemand;
2047c5a4c82aSJason M. Bills     }
2048c5a4c82aSJason M. Bills     if (oemDiagStr == "Telemetry")
2049c5a4c82aSJason M. Bills     {
2050c5a4c82aSJason M. Bills         return OEMDiagnosticType::telemetry;
2051c5a4c82aSJason M. Bills     }
2052c5a4c82aSJason M. Bills 
2053c5a4c82aSJason M. Bills     return OEMDiagnosticType::invalid;
2054c5a4c82aSJason M. Bills }
2055c5a4c82aSJason M. Bills 
20567e860f15SJohn Edward Broadbent inline void requestRoutesCrashdumpCollect(App& app)
20571da66f75SEd Tanous {
20580fda0f12SGeorge Liu     BMCWEB_ROUTE(
20590fda0f12SGeorge Liu         app,
206022d268cbSEd Tanous         "/redfish/v1/Systems/<str>/LogServices/Crashdump/Actions/LogService.CollectDiagnosticData/")
206150d9f38aSMyung Bae         .privileges(redfish::privileges::
206250d9f38aSMyung Bae                         postLogServiceSubOverComputerSystemLogServiceCollection)
2063002d39b4SEd Tanous         .methods(boost::beast::http::verb::post)(
2064002d39b4SEd Tanous             [&app](const crow::Request& req,
206522d268cbSEd Tanous                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
206622d268cbSEd Tanous                    const std::string& systemName) {
20673ba00073SCarson Labrado                 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
206845ca1b86SEd Tanous                 {
206945ca1b86SEd Tanous                     return;
207045ca1b86SEd Tanous                 }
207122d268cbSEd Tanous 
207225b54dbaSEd Tanous                 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
20737f3e84a1SEd Tanous                 {
20747f3e84a1SEd Tanous                     // Option currently returns no systems.  TBD
20757f3e84a1SEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
20767f3e84a1SEd Tanous                                                systemName);
20777f3e84a1SEd Tanous                     return;
20787f3e84a1SEd Tanous                 }
2079253f11b8SEd Tanous                 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
208022d268cbSEd Tanous                 {
208122d268cbSEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
208222d268cbSEd Tanous                                                systemName);
208322d268cbSEd Tanous                     return;
208422d268cbSEd Tanous                 }
208522d268cbSEd Tanous 
20868e6c099aSJason M. Bills                 std::string diagnosticDataType;
20878e6c099aSJason M. Bills                 std::string oemDiagnosticDataType;
2088afc474aeSMyung Bae                 if (!redfish::json_util::readJsonAction(               //
2089afc474aeSMyung Bae                         req, asyncResp->res,                           //
2090afc474aeSMyung Bae                         "DiagnosticDataType", diagnosticDataType,      //
2091afc474aeSMyung Bae                         "OEMDiagnosticDataType", oemDiagnosticDataType //
2092afc474aeSMyung Bae                         ))
20938e6c099aSJason M. Bills                 {
20948e6c099aSJason M. Bills                     return;
20958e6c099aSJason M. Bills                 }
20968e6c099aSJason M. Bills 
20978e6c099aSJason M. Bills                 if (diagnosticDataType != "OEM")
20988e6c099aSJason M. Bills                 {
209962598e31SEd Tanous                     BMCWEB_LOG_ERROR(
210062598e31SEd Tanous                         "Only OEM DiagnosticDataType supported for Crashdump");
21018e6c099aSJason M. Bills                     messages::actionParameterValueFormatError(
2102bd79bce8SPatrick Williams                         asyncResp->res, diagnosticDataType,
2103bd79bce8SPatrick Williams                         "DiagnosticDataType", "CollectDiagnosticData");
21048e6c099aSJason M. Bills                     return;
21058e6c099aSJason M. Bills                 }
21068e6c099aSJason M. Bills 
2107c5a4c82aSJason M. Bills                 OEMDiagnosticType oemDiagType =
2108c5a4c82aSJason M. Bills                     getOEMDiagnosticType(oemDiagnosticDataType);
2109c5a4c82aSJason M. Bills 
2110c5a4c82aSJason M. Bills                 std::string iface;
2111c5a4c82aSJason M. Bills                 std::string method;
2112c5a4c82aSJason M. Bills                 std::string taskMatchStr;
2113c5a4c82aSJason M. Bills                 if (oemDiagType == OEMDiagnosticType::onDemand)
2114c5a4c82aSJason M. Bills                 {
2115c5a4c82aSJason M. Bills                     iface = crashdumpOnDemandInterface;
2116c5a4c82aSJason M. Bills                     method = "GenerateOnDemandLog";
2117bd79bce8SPatrick Williams                     taskMatchStr =
2118bd79bce8SPatrick Williams                         "type='signal',"
2119c5a4c82aSJason M. Bills                         "interface='org.freedesktop.DBus.Properties',"
2120c5a4c82aSJason M. Bills                         "member='PropertiesChanged',"
2121c5a4c82aSJason M. Bills                         "arg0namespace='com.intel.crashdump'";
2122c5a4c82aSJason M. Bills                 }
2123c5a4c82aSJason M. Bills                 else if (oemDiagType == OEMDiagnosticType::telemetry)
2124c5a4c82aSJason M. Bills                 {
2125c5a4c82aSJason M. Bills                     iface = crashdumpTelemetryInterface;
2126c5a4c82aSJason M. Bills                     method = "GenerateTelemetryLog";
2127bd79bce8SPatrick Williams                     taskMatchStr =
2128bd79bce8SPatrick Williams                         "type='signal',"
2129c5a4c82aSJason M. Bills                         "interface='org.freedesktop.DBus.Properties',"
2130c5a4c82aSJason M. Bills                         "member='PropertiesChanged',"
2131c5a4c82aSJason M. Bills                         "arg0namespace='com.intel.crashdump'";
2132c5a4c82aSJason M. Bills                 }
2133c5a4c82aSJason M. Bills                 else
2134c5a4c82aSJason M. Bills                 {
213562598e31SEd Tanous                     BMCWEB_LOG_ERROR("Unsupported OEMDiagnosticDataType: {}",
213662598e31SEd Tanous                                      oemDiagnosticDataType);
2137c5a4c82aSJason M. Bills                     messages::actionParameterValueFormatError(
2138bd79bce8SPatrick Williams                         asyncResp->res, oemDiagnosticDataType,
2139bd79bce8SPatrick Williams                         "OEMDiagnosticDataType", "CollectDiagnosticData");
2140c5a4c82aSJason M. Bills                     return;
2141c5a4c82aSJason M. Bills                 }
2142c5a4c82aSJason M. Bills 
2143c5a4c82aSJason M. Bills                 auto collectCrashdumpCallback =
2144c5a4c82aSJason M. Bills                     [asyncResp, payload(task::Payload(req)),
21455e7e2dc5SEd Tanous                      taskMatchStr](const boost::system::error_code& ec,
214698be3e39SEd Tanous                                    const std::string&) mutable {
21471da66f75SEd Tanous                         if (ec)
21481da66f75SEd Tanous                         {
2149bd79bce8SPatrick Williams                             if (ec.value() ==
2150bd79bce8SPatrick Williams                                 boost::system::errc::operation_not_supported)
21511da66f75SEd Tanous                             {
2152f12894f8SJason M. Bills                                 messages::resourceInStandby(asyncResp->res);
21531da66f75SEd Tanous                             }
2154bd79bce8SPatrick Williams                             else if (ec.value() == boost::system::errc::
2155bd79bce8SPatrick Williams                                                        device_or_resource_busy)
21564363d3b2SJason M. Bills                             {
2157bd79bce8SPatrick Williams                                 messages::serviceTemporarilyUnavailable(
2158bd79bce8SPatrick Williams                                     asyncResp->res, "60");
21594363d3b2SJason M. Bills                             }
21601da66f75SEd Tanous                             else
21611da66f75SEd Tanous                             {
2162f12894f8SJason M. Bills                                 messages::internalError(asyncResp->res);
21631da66f75SEd Tanous                             }
21641da66f75SEd Tanous                             return;
21651da66f75SEd Tanous                         }
2166bd79bce8SPatrick Williams                         std::shared_ptr<task::TaskData> task =
2167bd79bce8SPatrick Williams                             task::TaskData::createTask(
2168bd79bce8SPatrick Williams                                 [](const boost::system::error_code& ec2,
2169bd79bce8SPatrick Williams                                    sdbusplus::message_t&,
2170bd79bce8SPatrick Williams                                    const std::shared_ptr<task::TaskData>&
2171bd79bce8SPatrick Williams                                        taskData) {
21728b24275dSEd Tanous                                     if (!ec2)
217366afe4faSJames Feist                                     {
2174bd79bce8SPatrick Williams                                         taskData->messages.emplace_back(
2175bd79bce8SPatrick Williams                                             messages::taskCompletedOK(
2176bd79bce8SPatrick Williams                                                 std::to_string(
2177bd79bce8SPatrick Williams                                                     taskData->index)));
2178831d6b09SJames Feist                                         taskData->state = "Completed";
217966afe4faSJames Feist                                     }
218032898ceaSJames Feist                                     return task::completed;
218166afe4faSJames Feist                                 },
2182c5a4c82aSJason M. Bills                                 taskMatchStr);
2183c5a4c82aSJason M. Bills 
218446229577SJames Feist                         task->startTimer(std::chrono::minutes(5));
218598be3e39SEd Tanous                         task->payload.emplace(std::move(payload));
218629e2bdd7SChinmay Shripad Hegde                         task->populateResp(asyncResp->res);
21871da66f75SEd Tanous                     };
21888e6c099aSJason M. Bills 
2189177612aaSEd Tanous                 dbus::utility::async_method_call(
2190177612aaSEd Tanous                     asyncResp, std::move(collectCrashdumpCallback),
2191177612aaSEd Tanous                     crashdumpObject, crashdumpPath, iface, method);
21927e860f15SJohn Edward Broadbent             });
21936eda7685SKenny L. Ku }
21941da66f75SEd Tanous } // namespace redfish
2195