xref: /openbmc/bmcweb/features/redfish/lib/log_services.hpp (revision ff35df942a0f173013cca54e5dfda3d3c5f5332d)
140e9b92eSEd Tanous // SPDX-License-Identifier: Apache-2.0
240e9b92eSEd Tanous // SPDX-FileCopyrightText: Copyright OpenBMC Authors
340e9b92eSEd Tanous // SPDX-FileCopyrightText: Copyright 2018 Intel Corporation
41da66f75SEd Tanous #pragma once
51da66f75SEd Tanous 
6d7857201SEd Tanous #include "bmcweb_config.h"
7d7857201SEd Tanous 
83ccb3adbSEd Tanous #include "app.hpp"
9d7857201SEd Tanous #include "async_resp.hpp"
10d7857201SEd Tanous #include "dbus_singleton.hpp"
117a1dbc48SGeorge Liu #include "dbus_utility.hpp"
123ccb3adbSEd Tanous #include "error_messages.hpp"
1368dd075aSAsmitha Karunanithi #include "generated/enums/log_entry.hpp"
14539d8c6bSEd Tanous #include "generated/enums/log_service.hpp"
15d7857201SEd Tanous #include "http_body.hpp"
16d7857201SEd Tanous #include "http_request.hpp"
17d7857201SEd Tanous #include "http_response.hpp"
18647b3cdcSGeorge Liu #include "http_utility.hpp"
19b7028ebfSSpencer Ku #include "human_sort.hpp"
20d7857201SEd Tanous #include "logging.hpp"
213ccb3adbSEd Tanous #include "query.hpp"
224851d45dSJason M. Bills #include "registries.hpp"
233ccb3adbSEd Tanous #include "registries/privilege_registry.hpp"
24d7857201SEd Tanous #include "str_utility.hpp"
2546229577SJames Feist #include "task.hpp"
265b90429aSEd Tanous #include "task_messages.hpp"
27262dcc1cSAlexander Hansen #include "utils/dbus_event_log_entry.hpp"
283ccb3adbSEd Tanous #include "utils/dbus_utils.hpp"
295b90429aSEd Tanous #include "utils/json_utils.hpp"
30*ff35df94SOliver Brewka #include "utils/log_services_utils.hpp"
31d7857201SEd Tanous #include "utils/query_param.hpp"
323ccb3adbSEd Tanous #include "utils/time_utils.hpp"
331da66f75SEd Tanous 
34d7857201SEd Tanous #include <asm-generic/errno.h>
35d7857201SEd Tanous #include <systemd/sd-bus.h>
368e31778eSAsmitha Karunanithi #include <tinyxml2.h>
37400fd1fbSAdriana Kobylak #include <unistd.h>
38e1f26343SJason M. Bills 
39d7857201SEd Tanous #include <boost/beast/http/field.hpp>
40d7857201SEd Tanous #include <boost/beast/http/status.hpp>
4107c8c20dSEd Tanous #include <boost/beast/http/verb.hpp>
421ddcf01aSJason M. Bills #include <boost/system/linux_error.hpp>
43ef4c65b7SEd Tanous #include <boost/url/format.hpp>
44d7857201SEd Tanous #include <boost/url/url.hpp>
45d7857201SEd Tanous #include <sdbusplus/message.hpp>
46d7857201SEd Tanous #include <sdbusplus/message/native_types.hpp>
47d1bde9e5SKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp>
481214b7e7SGunnar Mills 
49d7857201SEd Tanous #include <algorithm>
507a1dbc48SGeorge Liu #include <array>
51d7857201SEd Tanous #include <chrono>
52b5f288d2SAbhilash Raju #include <cstddef>
53d7857201SEd Tanous #include <cstdint>
54d7857201SEd Tanous #include <cstdio>
55d7857201SEd Tanous #include <ctime>
564418c7f0SJames Feist #include <filesystem>
57d7857201SEd Tanous #include <format>
58d7857201SEd Tanous #include <fstream>
59d7857201SEd Tanous #include <functional>
60d7857201SEd Tanous #include <iomanip>
6118f8f608SEd Tanous #include <iterator>
62d7857201SEd Tanous #include <memory>
6375710de2SXiaochao Ma #include <optional>
643544d2a7SEd Tanous #include <ranges>
6526702d01SEd Tanous #include <span>
66d7857201SEd Tanous #include <sstream>
6718f8f608SEd Tanous #include <string>
68cd225da8SJason M. Bills #include <string_view>
69d7857201SEd Tanous #include <system_error>
70d7857201SEd Tanous #include <utility>
71abf2add6SEd Tanous #include <variant>
72d7857201SEd Tanous #include <vector>
731da66f75SEd Tanous 
741da66f75SEd Tanous namespace redfish
751da66f75SEd Tanous {
761da66f75SEd Tanous 
7789492a15SPatrick Williams constexpr const char* crashdumpObject = "com.intel.crashdump";
7889492a15SPatrick Williams constexpr const char* crashdumpPath = "/com/intel/crashdump";
7989492a15SPatrick Williams constexpr const char* crashdumpInterface = "com.intel.crashdump";
8089492a15SPatrick Williams constexpr const char* deleteAllInterface =
815b61b5e8SJason M. Bills     "xyz.openbmc_project.Collection.DeleteAll";
8289492a15SPatrick Williams constexpr const char* crashdumpOnDemandInterface =
83424c4176SJason M. Bills     "com.intel.crashdump.OnDemand";
8489492a15SPatrick Williams constexpr const char* crashdumpTelemetryInterface =
856eda7685SKenny L. Ku     "com.intel.crashdump.Telemetry";
861da66f75SEd Tanous 
878e31778eSAsmitha Karunanithi enum class DumpCreationProgress
888e31778eSAsmitha Karunanithi {
898e31778eSAsmitha Karunanithi     DUMP_CREATE_SUCCESS,
908e31778eSAsmitha Karunanithi     DUMP_CREATE_FAILED,
918e31778eSAsmitha Karunanithi     DUMP_CREATE_INPROGRESS
928e31778eSAsmitha Karunanithi };
938e31778eSAsmitha Karunanithi 
94cb92c03bSAndrew Geissler inline std::string translateSeverityDbusToRedfish(const std::string& s)
95cb92c03bSAndrew Geissler {
96d4d25793SEd Tanous     if ((s == "xyz.openbmc_project.Logging.Entry.Level.Alert") ||
97d4d25793SEd Tanous         (s == "xyz.openbmc_project.Logging.Entry.Level.Critical") ||
98d4d25793SEd Tanous         (s == "xyz.openbmc_project.Logging.Entry.Level.Emergency") ||
99d4d25793SEd Tanous         (s == "xyz.openbmc_project.Logging.Entry.Level.Error"))
100cb92c03bSAndrew Geissler     {
101cb92c03bSAndrew Geissler         return "Critical";
102cb92c03bSAndrew Geissler     }
1033174e4dfSEd Tanous     if ((s == "xyz.openbmc_project.Logging.Entry.Level.Debug") ||
104d4d25793SEd Tanous         (s == "xyz.openbmc_project.Logging.Entry.Level.Informational") ||
105d4d25793SEd Tanous         (s == "xyz.openbmc_project.Logging.Entry.Level.Notice"))
106cb92c03bSAndrew Geissler     {
107cb92c03bSAndrew Geissler         return "OK";
108cb92c03bSAndrew Geissler     }
1093174e4dfSEd Tanous     if (s == "xyz.openbmc_project.Logging.Entry.Level.Warning")
110cb92c03bSAndrew Geissler     {
111cb92c03bSAndrew Geissler         return "Warning";
112cb92c03bSAndrew Geissler     }
113cb92c03bSAndrew Geissler     return "";
114cb92c03bSAndrew Geissler }
115cb92c03bSAndrew Geissler 
1169017faf2SAbhishek Patel inline std::optional<bool> getProviderNotifyAction(const std::string& notify)
1179017faf2SAbhishek Patel {
1189017faf2SAbhishek Patel     std::optional<bool> notifyAction;
1199017faf2SAbhishek Patel     if (notify == "xyz.openbmc_project.Logging.Entry.Notify.Notify")
1209017faf2SAbhishek Patel     {
1219017faf2SAbhishek Patel         notifyAction = true;
1229017faf2SAbhishek Patel     }
1239017faf2SAbhishek Patel     else if (notify == "xyz.openbmc_project.Logging.Entry.Notify.Inhibit")
1249017faf2SAbhishek Patel     {
1259017faf2SAbhishek Patel         notifyAction = false;
1269017faf2SAbhishek Patel     }
1279017faf2SAbhishek Patel 
1289017faf2SAbhishek Patel     return notifyAction;
1299017faf2SAbhishek Patel }
1309017faf2SAbhishek Patel 
13118f8f608SEd Tanous inline std::string getDumpPath(std::string_view dumpType)
13218f8f608SEd Tanous {
13318f8f608SEd Tanous     std::string dbusDumpPath = "/xyz/openbmc_project/dump/";
13418f8f608SEd Tanous     std::ranges::transform(dumpType, std::back_inserter(dbusDumpPath),
13518f8f608SEd Tanous                            bmcweb::asciiToLower);
13618f8f608SEd Tanous 
13718f8f608SEd Tanous     return dbusDumpPath;
13818f8f608SEd Tanous }
13918f8f608SEd Tanous 
140055713e4SEd Tanous inline bool getUniqueEntryID(const std::string& logEntry, std::string& entryID,
141e85d6b16SJason M. Bills                              const bool firstEntry = true)
14295820184SJason M. Bills {
143271584abSEd Tanous     static time_t prevTs = 0;
14495820184SJason M. Bills     static int index = 0;
145e85d6b16SJason M. Bills     if (firstEntry)
146e85d6b16SJason M. Bills     {
147e85d6b16SJason M. Bills         prevTs = 0;
148e85d6b16SJason M. Bills     }
149e85d6b16SJason M. Bills 
15095820184SJason M. Bills     // Get the entry timestamp
151271584abSEd Tanous     std::time_t curTs = 0;
15295820184SJason M. Bills     std::tm timeStruct = {};
15395820184SJason M. Bills     std::istringstream entryStream(logEntry);
15495820184SJason M. Bills     if (entryStream >> std::get_time(&timeStruct, "%Y-%m-%dT%H:%M:%S"))
15595820184SJason M. Bills     {
15695820184SJason M. Bills         curTs = std::mktime(&timeStruct);
15795820184SJason M. Bills     }
15895820184SJason M. Bills     // If the timestamp isn't unique, increment the index
15995820184SJason M. Bills     if (curTs == prevTs)
16095820184SJason M. Bills     {
16195820184SJason M. Bills         index++;
16295820184SJason M. Bills     }
16395820184SJason M. Bills     else
16495820184SJason M. Bills     {
16595820184SJason M. Bills         // Otherwise, reset it
16695820184SJason M. Bills         index = 0;
16795820184SJason M. Bills     }
16895820184SJason M. Bills     // Save the timestamp
16995820184SJason M. Bills     prevTs = curTs;
17095820184SJason M. Bills 
17195820184SJason M. Bills     entryID = std::to_string(curTs);
17295820184SJason M. Bills     if (index > 0)
17395820184SJason M. Bills     {
17495820184SJason M. Bills         entryID += "_" + std::to_string(index);
17595820184SJason M. Bills     }
17695820184SJason M. Bills     return true;
17795820184SJason M. Bills }
17895820184SJason M. Bills 
179504af5a0SPatrick Williams inline bool getRedfishLogFiles(
180504af5a0SPatrick Williams     std::vector<std::filesystem::path>& redfishLogFiles)
18195820184SJason M. Bills {
18295820184SJason M. Bills     static const std::filesystem::path redfishLogDir = "/var/log";
18395820184SJason M. Bills     static const std::string redfishLogFilename = "redfish";
18495820184SJason M. Bills 
18595820184SJason M. Bills     // Loop through the directory looking for redfish log files
18695820184SJason M. Bills     for (const std::filesystem::directory_entry& dirEnt :
18795820184SJason M. Bills          std::filesystem::directory_iterator(redfishLogDir))
18895820184SJason M. Bills     {
18995820184SJason M. Bills         // If we find a redfish log file, save the path
19095820184SJason M. Bills         std::string filename = dirEnt.path().filename();
19111ba3979SEd Tanous         if (filename.starts_with(redfishLogFilename))
19295820184SJason M. Bills         {
19395820184SJason M. Bills             redfishLogFiles.emplace_back(redfishLogDir / filename);
19495820184SJason M. Bills         }
19595820184SJason M. Bills     }
19695820184SJason M. Bills     // As the log files rotate, they are appended with a ".#" that is higher for
19795820184SJason M. Bills     // the older logs. Since we don't expect more than 10 log files, we
19895820184SJason M. Bills     // can just sort the list to get them in order from newest to oldest
1993544d2a7SEd Tanous     std::ranges::sort(redfishLogFiles);
20095820184SJason M. Bills 
20195820184SJason M. Bills     return !redfishLogFiles.empty();
20295820184SJason M. Bills }
20395820184SJason M. Bills 
204504af5a0SPatrick Williams inline log_entry::OriginatorTypes mapDbusOriginatorTypeToRedfish(
205504af5a0SPatrick Williams     const std::string& originatorType)
20668dd075aSAsmitha Karunanithi {
20768dd075aSAsmitha Karunanithi     if (originatorType ==
20868dd075aSAsmitha Karunanithi         "xyz.openbmc_project.Common.OriginatedBy.OriginatorTypes.Client")
20968dd075aSAsmitha Karunanithi     {
21068dd075aSAsmitha Karunanithi         return log_entry::OriginatorTypes::Client;
21168dd075aSAsmitha Karunanithi     }
21268dd075aSAsmitha Karunanithi     if (originatorType ==
21368dd075aSAsmitha Karunanithi         "xyz.openbmc_project.Common.OriginatedBy.OriginatorTypes.Internal")
21468dd075aSAsmitha Karunanithi     {
21568dd075aSAsmitha Karunanithi         return log_entry::OriginatorTypes::Internal;
21668dd075aSAsmitha Karunanithi     }
21768dd075aSAsmitha Karunanithi     if (originatorType ==
21868dd075aSAsmitha Karunanithi         "xyz.openbmc_project.Common.OriginatedBy.OriginatorTypes.SupportingService")
21968dd075aSAsmitha Karunanithi     {
22068dd075aSAsmitha Karunanithi         return log_entry::OriginatorTypes::SupportingService;
22168dd075aSAsmitha Karunanithi     }
22268dd075aSAsmitha Karunanithi     return log_entry::OriginatorTypes::Invalid;
22368dd075aSAsmitha Karunanithi }
22468dd075aSAsmitha Karunanithi 
225aefe3786SClaire Weinan inline void parseDumpEntryFromDbusObject(
2262d613eb6SJiaqing Zhao     const dbus::utility::ManagedObjectType::value_type& object,
227c6fecdabSClaire Weinan     std::string& dumpStatus, uint64_t& size, uint64_t& timestampUs,
22868dd075aSAsmitha Karunanithi     std::string& originatorId, log_entry::OriginatorTypes& originatorType,
229aefe3786SClaire Weinan     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
230aefe3786SClaire Weinan {
231aefe3786SClaire Weinan     for (const auto& interfaceMap : object.second)
232aefe3786SClaire Weinan     {
233aefe3786SClaire Weinan         if (interfaceMap.first == "xyz.openbmc_project.Common.Progress")
234aefe3786SClaire Weinan         {
235aefe3786SClaire Weinan             for (const auto& propertyMap : interfaceMap.second)
236aefe3786SClaire Weinan             {
237aefe3786SClaire Weinan                 if (propertyMap.first == "Status")
238aefe3786SClaire Weinan                 {
239aefe3786SClaire Weinan                     const auto* status =
240aefe3786SClaire Weinan                         std::get_if<std::string>(&propertyMap.second);
241aefe3786SClaire Weinan                     if (status == nullptr)
242aefe3786SClaire Weinan                     {
243aefe3786SClaire Weinan                         messages::internalError(asyncResp->res);
244aefe3786SClaire Weinan                         break;
245aefe3786SClaire Weinan                     }
246aefe3786SClaire Weinan                     dumpStatus = *status;
247aefe3786SClaire Weinan                 }
248aefe3786SClaire Weinan             }
249aefe3786SClaire Weinan         }
250aefe3786SClaire Weinan         else if (interfaceMap.first == "xyz.openbmc_project.Dump.Entry")
251aefe3786SClaire Weinan         {
252aefe3786SClaire Weinan             for (const auto& propertyMap : interfaceMap.second)
253aefe3786SClaire Weinan             {
254aefe3786SClaire Weinan                 if (propertyMap.first == "Size")
255aefe3786SClaire Weinan                 {
256aefe3786SClaire Weinan                     const auto* sizePtr =
257aefe3786SClaire Weinan                         std::get_if<uint64_t>(&propertyMap.second);
258aefe3786SClaire Weinan                     if (sizePtr == nullptr)
259aefe3786SClaire Weinan                     {
260aefe3786SClaire Weinan                         messages::internalError(asyncResp->res);
261aefe3786SClaire Weinan                         break;
262aefe3786SClaire Weinan                     }
263aefe3786SClaire Weinan                     size = *sizePtr;
264aefe3786SClaire Weinan                     break;
265aefe3786SClaire Weinan                 }
266aefe3786SClaire Weinan             }
267aefe3786SClaire Weinan         }
268aefe3786SClaire Weinan         else if (interfaceMap.first == "xyz.openbmc_project.Time.EpochTime")
269aefe3786SClaire Weinan         {
270aefe3786SClaire Weinan             for (const auto& propertyMap : interfaceMap.second)
271aefe3786SClaire Weinan             {
272aefe3786SClaire Weinan                 if (propertyMap.first == "Elapsed")
273aefe3786SClaire Weinan                 {
274aefe3786SClaire Weinan                     const uint64_t* usecsTimeStamp =
275aefe3786SClaire Weinan                         std::get_if<uint64_t>(&propertyMap.second);
276aefe3786SClaire Weinan                     if (usecsTimeStamp == nullptr)
277aefe3786SClaire Weinan                     {
278aefe3786SClaire Weinan                         messages::internalError(asyncResp->res);
279aefe3786SClaire Weinan                         break;
280aefe3786SClaire Weinan                     }
281c6fecdabSClaire Weinan                     timestampUs = *usecsTimeStamp;
282aefe3786SClaire Weinan                     break;
283aefe3786SClaire Weinan                 }
284aefe3786SClaire Weinan             }
285aefe3786SClaire Weinan         }
28668dd075aSAsmitha Karunanithi         else if (interfaceMap.first ==
28768dd075aSAsmitha Karunanithi                  "xyz.openbmc_project.Common.OriginatedBy")
28868dd075aSAsmitha Karunanithi         {
28968dd075aSAsmitha Karunanithi             for (const auto& propertyMap : interfaceMap.second)
29068dd075aSAsmitha Karunanithi             {
29168dd075aSAsmitha Karunanithi                 if (propertyMap.first == "OriginatorId")
29268dd075aSAsmitha Karunanithi                 {
29368dd075aSAsmitha Karunanithi                     const std::string* id =
29468dd075aSAsmitha Karunanithi                         std::get_if<std::string>(&propertyMap.second);
29568dd075aSAsmitha Karunanithi                     if (id == nullptr)
29668dd075aSAsmitha Karunanithi                     {
29768dd075aSAsmitha Karunanithi                         messages::internalError(asyncResp->res);
29868dd075aSAsmitha Karunanithi                         break;
29968dd075aSAsmitha Karunanithi                     }
30068dd075aSAsmitha Karunanithi                     originatorId = *id;
30168dd075aSAsmitha Karunanithi                 }
30268dd075aSAsmitha Karunanithi 
30368dd075aSAsmitha Karunanithi                 if (propertyMap.first == "OriginatorType")
30468dd075aSAsmitha Karunanithi                 {
30568dd075aSAsmitha Karunanithi                     const std::string* type =
30668dd075aSAsmitha Karunanithi                         std::get_if<std::string>(&propertyMap.second);
30768dd075aSAsmitha Karunanithi                     if (type == nullptr)
30868dd075aSAsmitha Karunanithi                     {
30968dd075aSAsmitha Karunanithi                         messages::internalError(asyncResp->res);
31068dd075aSAsmitha Karunanithi                         break;
31168dd075aSAsmitha Karunanithi                     }
31268dd075aSAsmitha Karunanithi 
31368dd075aSAsmitha Karunanithi                     originatorType = mapDbusOriginatorTypeToRedfish(*type);
31468dd075aSAsmitha Karunanithi                     if (originatorType == log_entry::OriginatorTypes::Invalid)
31568dd075aSAsmitha Karunanithi                     {
31668dd075aSAsmitha Karunanithi                         messages::internalError(asyncResp->res);
31768dd075aSAsmitha Karunanithi                         break;
31868dd075aSAsmitha Karunanithi                     }
31968dd075aSAsmitha Karunanithi                 }
32068dd075aSAsmitha Karunanithi             }
32168dd075aSAsmitha Karunanithi         }
322aefe3786SClaire Weinan     }
323aefe3786SClaire Weinan }
324aefe3786SClaire Weinan 
32521ab404cSNan Zhou static std::string getDumpEntriesPath(const std::string& dumpType)
326fdd26906SClaire Weinan {
327fdd26906SClaire Weinan     std::string entriesPath;
328fdd26906SClaire Weinan 
329fdd26906SClaire Weinan     if (dumpType == "BMC")
330fdd26906SClaire Weinan     {
331253f11b8SEd Tanous         entriesPath =
332253f11b8SEd Tanous             std::format("/redfish/v1/Managers/{}/LogServices/Dump/Entries/",
333253f11b8SEd Tanous                         BMCWEB_REDFISH_MANAGER_URI_NAME);
334fdd26906SClaire Weinan     }
335fdd26906SClaire Weinan     else if (dumpType == "FaultLog")
336fdd26906SClaire Weinan     {
337253f11b8SEd Tanous         entriesPath =
338253f11b8SEd Tanous             std::format("/redfish/v1/Managers/{}/LogServices/FaultLog/Entries/",
339253f11b8SEd Tanous                         BMCWEB_REDFISH_MANAGER_URI_NAME);
340fdd26906SClaire Weinan     }
341fdd26906SClaire Weinan     else if (dumpType == "System")
342fdd26906SClaire Weinan     {
343253f11b8SEd Tanous         entriesPath =
344253f11b8SEd Tanous             std::format("/redfish/v1/Systems/{}/LogServices/Dump/Entries/",
345253f11b8SEd Tanous                         BMCWEB_REDFISH_SYSTEM_URI_NAME);
346fdd26906SClaire Weinan     }
347fdd26906SClaire Weinan     else
348fdd26906SClaire Weinan     {
34962598e31SEd Tanous         BMCWEB_LOG_ERROR("getDumpEntriesPath() invalid dump type: {}",
35062598e31SEd Tanous                          dumpType);
351fdd26906SClaire Weinan     }
352fdd26906SClaire Weinan 
353fdd26906SClaire Weinan     // Returns empty string on error
354fdd26906SClaire Weinan     return entriesPath;
355fdd26906SClaire Weinan }
356fdd26906SClaire Weinan 
357504af5a0SPatrick Williams inline void getDumpEntryCollection(
358504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3595cb1dd27SAsmitha Karunanithi     const std::string& dumpType)
3605cb1dd27SAsmitha Karunanithi {
361fdd26906SClaire Weinan     std::string entriesPath = getDumpEntriesPath(dumpType);
362fdd26906SClaire Weinan     if (entriesPath.empty())
3635cb1dd27SAsmitha Karunanithi     {
3645cb1dd27SAsmitha Karunanithi         messages::internalError(asyncResp->res);
3655cb1dd27SAsmitha Karunanithi         return;
3665cb1dd27SAsmitha Karunanithi     }
3675cb1dd27SAsmitha Karunanithi 
3685eb468daSGeorge Liu     sdbusplus::message::object_path path("/xyz/openbmc_project/dump");
3695eb468daSGeorge Liu     dbus::utility::getManagedObjects(
3705eb468daSGeorge Liu         "xyz.openbmc_project.Dump.Manager", path,
371fdd26906SClaire Weinan         [asyncResp, entriesPath,
3725e7e2dc5SEd Tanous          dumpType](const boost::system::error_code& ec,
3735eb468daSGeorge Liu                    const dbus::utility::ManagedObjectType& objects) {
3745cb1dd27SAsmitha Karunanithi             if (ec)
3755cb1dd27SAsmitha Karunanithi             {
37662598e31SEd Tanous                 BMCWEB_LOG_ERROR("DumpEntry resp_handler got error {}", ec);
3775cb1dd27SAsmitha Karunanithi                 messages::internalError(asyncResp->res);
3785cb1dd27SAsmitha Karunanithi                 return;
3795cb1dd27SAsmitha Karunanithi             }
3805cb1dd27SAsmitha Karunanithi 
381fdd26906SClaire Weinan             // Remove ending slash
382fdd26906SClaire Weinan             std::string odataIdStr = entriesPath;
383fdd26906SClaire Weinan             if (!odataIdStr.empty())
384fdd26906SClaire Weinan             {
385fdd26906SClaire Weinan                 odataIdStr.pop_back();
386fdd26906SClaire Weinan             }
387fdd26906SClaire Weinan 
388fdd26906SClaire Weinan             asyncResp->res.jsonValue["@odata.type"] =
389fdd26906SClaire Weinan                 "#LogEntryCollection.LogEntryCollection";
390fdd26906SClaire Weinan             asyncResp->res.jsonValue["@odata.id"] = std::move(odataIdStr);
391fdd26906SClaire Weinan             asyncResp->res.jsonValue["Name"] = dumpType + " Dump Entries";
392bd79bce8SPatrick Williams             asyncResp->res.jsonValue["Description"] =
393bd79bce8SPatrick Williams                 "Collection of " + dumpType + " Dump Entries";
394fdd26906SClaire Weinan 
3953544d2a7SEd Tanous             nlohmann::json::array_t entriesArray;
39618f8f608SEd Tanous             std::string dumpEntryPath = getDumpPath(dumpType) + "/entry/";
3975cb1dd27SAsmitha Karunanithi 
3985eb468daSGeorge Liu             dbus::utility::ManagedObjectType resp(objects);
3993544d2a7SEd Tanous             std::ranges::sort(resp, [](const auto& l, const auto& r) {
400002d39b4SEd Tanous                 return AlphanumLess<std::string>()(l.first.filename(),
401002d39b4SEd Tanous                                                    r.first.filename());
402565dfb6fSClaire Weinan             });
403565dfb6fSClaire Weinan 
4045cb1dd27SAsmitha Karunanithi             for (auto& object : resp)
4055cb1dd27SAsmitha Karunanithi             {
406b47452b2SAsmitha Karunanithi                 if (object.first.str.find(dumpEntryPath) == std::string::npos)
4075cb1dd27SAsmitha Karunanithi                 {
4085cb1dd27SAsmitha Karunanithi                     continue;
4095cb1dd27SAsmitha Karunanithi                 }
410c6fecdabSClaire Weinan                 uint64_t timestampUs = 0;
4115cb1dd27SAsmitha Karunanithi                 uint64_t size = 0;
41235440d18SAsmitha Karunanithi                 std::string dumpStatus;
41368dd075aSAsmitha Karunanithi                 std::string originatorId;
41468dd075aSAsmitha Karunanithi                 log_entry::OriginatorTypes originatorType =
41568dd075aSAsmitha Karunanithi                     log_entry::OriginatorTypes::Internal;
416433b68b4SJason M. Bills                 nlohmann::json::object_t thisEntry;
4172dfd18efSEd Tanous 
4182dfd18efSEd Tanous                 std::string entryID = object.first.filename();
4192dfd18efSEd Tanous                 if (entryID.empty())
4205cb1dd27SAsmitha Karunanithi                 {
4215cb1dd27SAsmitha Karunanithi                     continue;
4225cb1dd27SAsmitha Karunanithi                 }
4235cb1dd27SAsmitha Karunanithi 
424bd79bce8SPatrick Williams                 parseDumpEntryFromDbusObject(object, dumpStatus, size,
425bd79bce8SPatrick Williams                                              timestampUs, originatorId,
426bd79bce8SPatrick Williams                                              originatorType, asyncResp);
4275cb1dd27SAsmitha Karunanithi 
4280fda0f12SGeorge Liu                 if (dumpStatus !=
4290fda0f12SGeorge Liu                         "xyz.openbmc_project.Common.Progress.OperationStatus.Completed" &&
43035440d18SAsmitha Karunanithi                     !dumpStatus.empty())
43135440d18SAsmitha Karunanithi                 {
43235440d18SAsmitha Karunanithi                     // Dump status is not Complete, no need to enumerate
43335440d18SAsmitha Karunanithi                     continue;
43435440d18SAsmitha Karunanithi                 }
43535440d18SAsmitha Karunanithi 
43668dd075aSAsmitha Karunanithi                 thisEntry["@odata.type"] = "#LogEntry.v1_11_0.LogEntry";
437fdd26906SClaire Weinan                 thisEntry["@odata.id"] = entriesPath + entryID;
4385cb1dd27SAsmitha Karunanithi                 thisEntry["Id"] = entryID;
4395cb1dd27SAsmitha Karunanithi                 thisEntry["EntryType"] = "Event";
4405cb1dd27SAsmitha Karunanithi                 thisEntry["Name"] = dumpType + " Dump Entry";
441bbd80db8SClaire Weinan                 thisEntry["Created"] =
442bbd80db8SClaire Weinan                     redfish::time_utils::getDateTimeUintUs(timestampUs);
4435cb1dd27SAsmitha Karunanithi 
44468dd075aSAsmitha Karunanithi                 if (!originatorId.empty())
44568dd075aSAsmitha Karunanithi                 {
44668dd075aSAsmitha Karunanithi                     thisEntry["Originator"] = originatorId;
44768dd075aSAsmitha Karunanithi                     thisEntry["OriginatorType"] = originatorType;
44868dd075aSAsmitha Karunanithi                 }
44968dd075aSAsmitha Karunanithi 
4505cb1dd27SAsmitha Karunanithi                 if (dumpType == "BMC")
4515cb1dd27SAsmitha Karunanithi                 {
452d337bb72SAsmitha Karunanithi                     thisEntry["DiagnosticDataType"] = "Manager";
453bd79bce8SPatrick Williams                     thisEntry["AdditionalDataURI"] =
454bd79bce8SPatrick Williams                         entriesPath + entryID + "/attachment";
455fdd26906SClaire Weinan                     thisEntry["AdditionalDataSizeBytes"] = size;
4565cb1dd27SAsmitha Karunanithi                 }
4575cb1dd27SAsmitha Karunanithi                 else if (dumpType == "System")
4585cb1dd27SAsmitha Karunanithi                 {
459d337bb72SAsmitha Karunanithi                     thisEntry["DiagnosticDataType"] = "OEM";
460d337bb72SAsmitha Karunanithi                     thisEntry["OEMDiagnosticDataType"] = "System";
461bd79bce8SPatrick Williams                     thisEntry["AdditionalDataURI"] =
462bd79bce8SPatrick Williams                         entriesPath + entryID + "/attachment";
463fdd26906SClaire Weinan                     thisEntry["AdditionalDataSizeBytes"] = size;
4645cb1dd27SAsmitha Karunanithi                 }
465b2ba3072SPatrick Williams                 entriesArray.emplace_back(std::move(thisEntry));
4665cb1dd27SAsmitha Karunanithi             }
467bd79bce8SPatrick Williams             asyncResp->res.jsonValue["Members@odata.count"] =
468bd79bce8SPatrick Williams                 entriesArray.size();
4693544d2a7SEd Tanous             asyncResp->res.jsonValue["Members"] = std::move(entriesArray);
4705eb468daSGeorge Liu         });
4715cb1dd27SAsmitha Karunanithi }
4725cb1dd27SAsmitha Karunanithi 
473504af5a0SPatrick Williams inline void getDumpEntryById(
474504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
4758d1b46d7Szhanghch05     const std::string& entryID, const std::string& dumpType)
4765cb1dd27SAsmitha Karunanithi {
477fdd26906SClaire Weinan     std::string entriesPath = getDumpEntriesPath(dumpType);
478fdd26906SClaire Weinan     if (entriesPath.empty())
4795cb1dd27SAsmitha Karunanithi     {
4805cb1dd27SAsmitha Karunanithi         messages::internalError(asyncResp->res);
4815cb1dd27SAsmitha Karunanithi         return;
4825cb1dd27SAsmitha Karunanithi     }
4835cb1dd27SAsmitha Karunanithi 
4845eb468daSGeorge Liu     sdbusplus::message::object_path path("/xyz/openbmc_project/dump");
4855eb468daSGeorge Liu     dbus::utility::getManagedObjects(
4865eb468daSGeorge Liu         "xyz.openbmc_project.Dump.Manager", path,
487fdd26906SClaire Weinan         [asyncResp, entryID, dumpType,
4885e7e2dc5SEd Tanous          entriesPath](const boost::system::error_code& ec,
48902cad96eSEd Tanous                       const dbus::utility::ManagedObjectType& resp) {
4905cb1dd27SAsmitha Karunanithi             if (ec)
4915cb1dd27SAsmitha Karunanithi             {
49262598e31SEd Tanous                 BMCWEB_LOG_ERROR("DumpEntry resp_handler got error {}", ec);
4935cb1dd27SAsmitha Karunanithi                 messages::internalError(asyncResp->res);
4945cb1dd27SAsmitha Karunanithi                 return;
4955cb1dd27SAsmitha Karunanithi             }
4965cb1dd27SAsmitha Karunanithi 
497b47452b2SAsmitha Karunanithi             bool foundDumpEntry = false;
49818f8f608SEd Tanous             std::string dumpEntryPath = getDumpPath(dumpType) + "/entry/";
499b47452b2SAsmitha Karunanithi 
5009eb808c1SEd Tanous             for (const auto& objectPath : resp)
5015cb1dd27SAsmitha Karunanithi             {
502b47452b2SAsmitha Karunanithi                 if (objectPath.first.str != dumpEntryPath + entryID)
5035cb1dd27SAsmitha Karunanithi                 {
5045cb1dd27SAsmitha Karunanithi                     continue;
5055cb1dd27SAsmitha Karunanithi                 }
5065cb1dd27SAsmitha Karunanithi 
5075cb1dd27SAsmitha Karunanithi                 foundDumpEntry = true;
508c6fecdabSClaire Weinan                 uint64_t timestampUs = 0;
5095cb1dd27SAsmitha Karunanithi                 uint64_t size = 0;
51035440d18SAsmitha Karunanithi                 std::string dumpStatus;
51168dd075aSAsmitha Karunanithi                 std::string originatorId;
51268dd075aSAsmitha Karunanithi                 log_entry::OriginatorTypes originatorType =
51368dd075aSAsmitha Karunanithi                     log_entry::OriginatorTypes::Internal;
5145cb1dd27SAsmitha Karunanithi 
515aefe3786SClaire Weinan                 parseDumpEntryFromDbusObject(objectPath, dumpStatus, size,
51668dd075aSAsmitha Karunanithi                                              timestampUs, originatorId,
51768dd075aSAsmitha Karunanithi                                              originatorType, asyncResp);
5185cb1dd27SAsmitha Karunanithi 
5190fda0f12SGeorge Liu                 if (dumpStatus !=
5200fda0f12SGeorge Liu                         "xyz.openbmc_project.Common.Progress.OperationStatus.Completed" &&
52135440d18SAsmitha Karunanithi                     !dumpStatus.empty())
52235440d18SAsmitha Karunanithi                 {
52335440d18SAsmitha Karunanithi                     // Dump status is not Complete
52435440d18SAsmitha Karunanithi                     // return not found until status is changed to Completed
525bd79bce8SPatrick Williams                     messages::resourceNotFound(asyncResp->res,
526bd79bce8SPatrick Williams                                                dumpType + " dump", entryID);
52735440d18SAsmitha Karunanithi                     return;
52835440d18SAsmitha Karunanithi                 }
52935440d18SAsmitha Karunanithi 
5305cb1dd27SAsmitha Karunanithi                 asyncResp->res.jsonValue["@odata.type"] =
53168dd075aSAsmitha Karunanithi                     "#LogEntry.v1_11_0.LogEntry";
532fdd26906SClaire Weinan                 asyncResp->res.jsonValue["@odata.id"] = entriesPath + entryID;
5335cb1dd27SAsmitha Karunanithi                 asyncResp->res.jsonValue["Id"] = entryID;
5345cb1dd27SAsmitha Karunanithi                 asyncResp->res.jsonValue["EntryType"] = "Event";
5355cb1dd27SAsmitha Karunanithi                 asyncResp->res.jsonValue["Name"] = dumpType + " Dump Entry";
536bbd80db8SClaire Weinan                 asyncResp->res.jsonValue["Created"] =
537bbd80db8SClaire Weinan                     redfish::time_utils::getDateTimeUintUs(timestampUs);
5385cb1dd27SAsmitha Karunanithi 
53968dd075aSAsmitha Karunanithi                 if (!originatorId.empty())
54068dd075aSAsmitha Karunanithi                 {
54168dd075aSAsmitha Karunanithi                     asyncResp->res.jsonValue["Originator"] = originatorId;
54268dd075aSAsmitha Karunanithi                     asyncResp->res.jsonValue["OriginatorType"] = originatorType;
54368dd075aSAsmitha Karunanithi                 }
54468dd075aSAsmitha Karunanithi 
5455cb1dd27SAsmitha Karunanithi                 if (dumpType == "BMC")
5465cb1dd27SAsmitha Karunanithi                 {
547d337bb72SAsmitha Karunanithi                     asyncResp->res.jsonValue["DiagnosticDataType"] = "Manager";
548d337bb72SAsmitha Karunanithi                     asyncResp->res.jsonValue["AdditionalDataURI"] =
549fdd26906SClaire Weinan                         entriesPath + entryID + "/attachment";
550fdd26906SClaire Weinan                     asyncResp->res.jsonValue["AdditionalDataSizeBytes"] = size;
5515cb1dd27SAsmitha Karunanithi                 }
5525cb1dd27SAsmitha Karunanithi                 else if (dumpType == "System")
5535cb1dd27SAsmitha Karunanithi                 {
554d337bb72SAsmitha Karunanithi                     asyncResp->res.jsonValue["DiagnosticDataType"] = "OEM";
555bd79bce8SPatrick Williams                     asyncResp->res.jsonValue["OEMDiagnosticDataType"] =
556bd79bce8SPatrick Williams                         "System";
557d337bb72SAsmitha Karunanithi                     asyncResp->res.jsonValue["AdditionalDataURI"] =
558fdd26906SClaire Weinan                         entriesPath + entryID + "/attachment";
559fdd26906SClaire Weinan                     asyncResp->res.jsonValue["AdditionalDataSizeBytes"] = size;
5605cb1dd27SAsmitha Karunanithi                 }
5615cb1dd27SAsmitha Karunanithi             }
562e05aec50SEd Tanous             if (!foundDumpEntry)
563b47452b2SAsmitha Karunanithi             {
56462598e31SEd Tanous                 BMCWEB_LOG_WARNING("Can't find Dump Entry {}", entryID);
565b90d14f2SMyung Bae                 messages::resourceNotFound(asyncResp->res, dumpType + " dump",
566b90d14f2SMyung Bae                                            entryID);
567b47452b2SAsmitha Karunanithi                 return;
568b47452b2SAsmitha Karunanithi             }
5695eb468daSGeorge Liu         });
5705cb1dd27SAsmitha Karunanithi }
5715cb1dd27SAsmitha Karunanithi 
5728d1b46d7Szhanghch05 inline void deleteDumpEntry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
5739878256fSStanley Chu                             const std::string& entryID,
574b47452b2SAsmitha Karunanithi                             const std::string& dumpType)
5755cb1dd27SAsmitha Karunanithi {
5765a39f77aSPatrick Williams     auto respHandler = [asyncResp,
5775a39f77aSPatrick Williams                         entryID](const boost::system::error_code& ec) {
57862598e31SEd Tanous         BMCWEB_LOG_DEBUG("Dump Entry doDelete callback: Done");
5795cb1dd27SAsmitha Karunanithi         if (ec)
5805cb1dd27SAsmitha Karunanithi         {
5813de8d8baSGeorge Liu             if (ec.value() == EBADR)
5823de8d8baSGeorge Liu             {
5833de8d8baSGeorge Liu                 messages::resourceNotFound(asyncResp->res, "LogEntry", entryID);
5843de8d8baSGeorge Liu                 return;
5853de8d8baSGeorge Liu             }
58662598e31SEd Tanous             BMCWEB_LOG_ERROR(
58762598e31SEd Tanous                 "Dump (DBus) doDelete respHandler got error {} entryID={}", ec,
58862598e31SEd Tanous                 entryID);
5895cb1dd27SAsmitha Karunanithi             messages::internalError(asyncResp->res);
5905cb1dd27SAsmitha Karunanithi             return;
5915cb1dd27SAsmitha Karunanithi         }
5925cb1dd27SAsmitha Karunanithi     };
59318f8f608SEd Tanous 
594177612aaSEd Tanous     dbus::utility::async_method_call(
595177612aaSEd Tanous         asyncResp, respHandler, "xyz.openbmc_project.Dump.Manager",
59618f8f608SEd Tanous         std::format("{}/entry/{}", getDumpPath(dumpType), entryID),
5975cb1dd27SAsmitha Karunanithi         "xyz.openbmc_project.Object.Delete", "Delete");
5985cb1dd27SAsmitha Karunanithi }
599168d1b1aSCarson Labrado 
600504af5a0SPatrick Williams inline void downloadDumpEntry(
601504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
602168d1b1aSCarson Labrado     const std::string& entryID, const std::string& dumpType)
603168d1b1aSCarson Labrado {
604168d1b1aSCarson Labrado     if (dumpType != "BMC")
605168d1b1aSCarson Labrado     {
606168d1b1aSCarson Labrado         BMCWEB_LOG_WARNING("Can't find Dump Entry {}", entryID);
607168d1b1aSCarson Labrado         messages::resourceNotFound(asyncResp->res, dumpType + " dump", entryID);
608168d1b1aSCarson Labrado         return;
609168d1b1aSCarson Labrado     }
610168d1b1aSCarson Labrado 
611bd79bce8SPatrick Williams     std::string dumpEntryPath =
612bd79bce8SPatrick Williams         std::format("{}/entry/{}", getDumpPath(dumpType), entryID);
613168d1b1aSCarson Labrado 
614168d1b1aSCarson Labrado     auto downloadDumpEntryHandler =
615168d1b1aSCarson Labrado         [asyncResp, entryID,
616168d1b1aSCarson Labrado          dumpType](const boost::system::error_code& ec,
617168d1b1aSCarson Labrado                    const sdbusplus::message::unix_fd& unixfd) {
618*ff35df94SOliver Brewka             log_services_utils::downloadEntryCallback(asyncResp, entryID,
619*ff35df94SOliver Brewka                                                       dumpType, ec, unixfd);
620168d1b1aSCarson Labrado         };
621168d1b1aSCarson Labrado 
622177612aaSEd Tanous     dbus::utility::async_method_call(
623177612aaSEd Tanous         asyncResp, std::move(downloadDumpEntryHandler),
624177612aaSEd Tanous         "xyz.openbmc_project.Dump.Manager", dumpEntryPath,
625177612aaSEd Tanous         "xyz.openbmc_project.Dump.Entry", "GetFileHandle");
626168d1b1aSCarson Labrado }
627168d1b1aSCarson Labrado 
628bd79bce8SPatrick Williams inline void downloadEventLogEntry(
629bd79bce8SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
630bd79bce8SPatrick Williams     const std::string& systemName, const std::string& entryID,
631168d1b1aSCarson Labrado     const std::string& dumpType)
632168d1b1aSCarson Labrado {
63325b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
634168d1b1aSCarson Labrado     {
635168d1b1aSCarson Labrado         // Option currently returns no systems.  TBD
636168d1b1aSCarson Labrado         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
637168d1b1aSCarson Labrado                                    systemName);
638168d1b1aSCarson Labrado         return;
639168d1b1aSCarson Labrado     }
640253f11b8SEd Tanous     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
641168d1b1aSCarson Labrado     {
642168d1b1aSCarson Labrado         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
643168d1b1aSCarson Labrado                                    systemName);
644168d1b1aSCarson Labrado         return;
645168d1b1aSCarson Labrado     }
646168d1b1aSCarson Labrado 
647168d1b1aSCarson Labrado     std::string entryPath =
648168d1b1aSCarson Labrado         sdbusplus::message::object_path("/xyz/openbmc_project/logging/entry") /
649168d1b1aSCarson Labrado         entryID;
650168d1b1aSCarson Labrado 
651168d1b1aSCarson Labrado     auto downloadEventLogEntryHandler =
652168d1b1aSCarson Labrado         [asyncResp, entryID,
653168d1b1aSCarson Labrado          dumpType](const boost::system::error_code& ec,
654168d1b1aSCarson Labrado                    const sdbusplus::message::unix_fd& unixfd) {
655*ff35df94SOliver Brewka             log_services_utils::downloadEntryCallback(asyncResp, entryID,
656*ff35df94SOliver Brewka                                                       dumpType, ec, unixfd);
657168d1b1aSCarson Labrado         };
658168d1b1aSCarson Labrado 
659177612aaSEd Tanous     dbus::utility::async_method_call(
660177612aaSEd Tanous         asyncResp, std::move(downloadEventLogEntryHandler),
661177612aaSEd Tanous         "xyz.openbmc_project.Logging", entryPath,
662177612aaSEd Tanous         "xyz.openbmc_project.Logging.Entry", "GetEntry");
663168d1b1aSCarson Labrado }
664168d1b1aSCarson Labrado 
665504af5a0SPatrick Williams inline DumpCreationProgress mapDbusStatusToDumpProgress(
666504af5a0SPatrick Williams     const std::string& status)
667a43be80fSAsmitha Karunanithi {
6688e31778eSAsmitha Karunanithi     if (status ==
6698e31778eSAsmitha Karunanithi             "xyz.openbmc_project.Common.Progress.OperationStatus.Failed" ||
6708e31778eSAsmitha Karunanithi         status == "xyz.openbmc_project.Common.Progress.OperationStatus.Aborted")
6718e31778eSAsmitha Karunanithi     {
6728e31778eSAsmitha Karunanithi         return DumpCreationProgress::DUMP_CREATE_FAILED;
6738e31778eSAsmitha Karunanithi     }
6748e31778eSAsmitha Karunanithi     if (status ==
6758e31778eSAsmitha Karunanithi         "xyz.openbmc_project.Common.Progress.OperationStatus.Completed")
6768e31778eSAsmitha Karunanithi     {
6778e31778eSAsmitha Karunanithi         return DumpCreationProgress::DUMP_CREATE_SUCCESS;
6788e31778eSAsmitha Karunanithi     }
6798e31778eSAsmitha Karunanithi     return DumpCreationProgress::DUMP_CREATE_INPROGRESS;
6808e31778eSAsmitha Karunanithi }
6818e31778eSAsmitha Karunanithi 
682504af5a0SPatrick Williams inline DumpCreationProgress getDumpCompletionStatus(
683504af5a0SPatrick Williams     const dbus::utility::DBusPropertiesMap& values)
6848e31778eSAsmitha Karunanithi {
6858e31778eSAsmitha Karunanithi     for (const auto& [key, val] : values)
6868e31778eSAsmitha Karunanithi     {
6878e31778eSAsmitha Karunanithi         if (key == "Status")
6888e31778eSAsmitha Karunanithi         {
6898e31778eSAsmitha Karunanithi             const std::string* value = std::get_if<std::string>(&val);
6908e31778eSAsmitha Karunanithi             if (value == nullptr)
6918e31778eSAsmitha Karunanithi             {
69262598e31SEd Tanous                 BMCWEB_LOG_ERROR("Status property value is null");
6938e31778eSAsmitha Karunanithi                 return DumpCreationProgress::DUMP_CREATE_FAILED;
6948e31778eSAsmitha Karunanithi             }
6958e31778eSAsmitha Karunanithi             return mapDbusStatusToDumpProgress(*value);
6968e31778eSAsmitha Karunanithi         }
6978e31778eSAsmitha Karunanithi     }
6988e31778eSAsmitha Karunanithi     return DumpCreationProgress::DUMP_CREATE_INPROGRESS;
6998e31778eSAsmitha Karunanithi }
7008e31778eSAsmitha Karunanithi 
7018e31778eSAsmitha Karunanithi inline std::string getDumpEntryPath(const std::string& dumpPath)
7028e31778eSAsmitha Karunanithi {
7038e31778eSAsmitha Karunanithi     if (dumpPath == "/xyz/openbmc_project/dump/bmc/entry")
7048e31778eSAsmitha Karunanithi     {
705253f11b8SEd Tanous         return std::format("/redfish/v1/Managers/{}/LogServices/Dump/Entries/",
7069f565090SEd Tanous                            BMCWEB_REDFISH_MANAGER_URI_NAME);
7078e31778eSAsmitha Karunanithi     }
7088e31778eSAsmitha Karunanithi     if (dumpPath == "/xyz/openbmc_project/dump/system/entry")
7098e31778eSAsmitha Karunanithi     {
710253f11b8SEd Tanous         return std::format("/redfish/v1/Systems/{}/LogServices/Dump/Entries/",
711253f11b8SEd Tanous                            BMCWEB_REDFISH_SYSTEM_URI_NAME);
7128e31778eSAsmitha Karunanithi     }
7138e31778eSAsmitha Karunanithi     return "";
7148e31778eSAsmitha Karunanithi }
7158e31778eSAsmitha Karunanithi 
7168e31778eSAsmitha Karunanithi inline void createDumpTaskCallback(
7178e31778eSAsmitha Karunanithi     task::Payload&& payload,
7188e31778eSAsmitha Karunanithi     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
7198e31778eSAsmitha Karunanithi     const sdbusplus::message::object_path& createdObjPath)
7208e31778eSAsmitha Karunanithi {
7218e31778eSAsmitha Karunanithi     const std::string dumpPath = createdObjPath.parent_path().str;
7228e31778eSAsmitha Karunanithi     const std::string dumpId = createdObjPath.filename();
7238e31778eSAsmitha Karunanithi 
7248e31778eSAsmitha Karunanithi     std::string dumpEntryPath = getDumpEntryPath(dumpPath);
7258e31778eSAsmitha Karunanithi 
7268e31778eSAsmitha Karunanithi     if (dumpEntryPath.empty())
7278e31778eSAsmitha Karunanithi     {
72862598e31SEd Tanous         BMCWEB_LOG_ERROR("Invalid dump type received");
7298e31778eSAsmitha Karunanithi         messages::internalError(asyncResp->res);
7308e31778eSAsmitha Karunanithi         return;
7318e31778eSAsmitha Karunanithi     }
7328e31778eSAsmitha Karunanithi 
733177612aaSEd Tanous     dbus::utility::async_method_call(
734177612aaSEd Tanous         asyncResp,
7358cb2c024SEd Tanous         [asyncResp, payload = std::move(payload), createdObjPath,
7368e31778eSAsmitha Karunanithi          dumpEntryPath{std::move(dumpEntryPath)},
7375e7e2dc5SEd Tanous          dumpId](const boost::system::error_code& ec,
7388e31778eSAsmitha Karunanithi                  const std::string& introspectXml) {
7398e31778eSAsmitha Karunanithi             if (ec)
7408e31778eSAsmitha Karunanithi             {
74162598e31SEd Tanous                 BMCWEB_LOG_ERROR("Introspect call failed with error: {}",
74262598e31SEd Tanous                                  ec.message());
7438e31778eSAsmitha Karunanithi                 messages::internalError(asyncResp->res);
7448e31778eSAsmitha Karunanithi                 return;
7458e31778eSAsmitha Karunanithi             }
7468e31778eSAsmitha Karunanithi 
7478e31778eSAsmitha Karunanithi             // Check if the created dump object has implemented Progress
7488e31778eSAsmitha Karunanithi             // interface to track dump completion. If yes, fetch the "Status"
7498e31778eSAsmitha Karunanithi             // property of the interface, modify the task state accordingly.
7508e31778eSAsmitha Karunanithi             // Else, return task completed.
7518e31778eSAsmitha Karunanithi             tinyxml2::XMLDocument doc;
7528e31778eSAsmitha Karunanithi 
7538e31778eSAsmitha Karunanithi             doc.Parse(introspectXml.data(), introspectXml.size());
7548e31778eSAsmitha Karunanithi             tinyxml2::XMLNode* pRoot = doc.FirstChildElement("node");
7558e31778eSAsmitha Karunanithi             if (pRoot == nullptr)
7568e31778eSAsmitha Karunanithi             {
75762598e31SEd Tanous                 BMCWEB_LOG_ERROR("XML document failed to parse");
7588e31778eSAsmitha Karunanithi                 messages::internalError(asyncResp->res);
7598e31778eSAsmitha Karunanithi                 return;
7608e31778eSAsmitha Karunanithi             }
7618e31778eSAsmitha Karunanithi             tinyxml2::XMLElement* interfaceNode =
7628e31778eSAsmitha Karunanithi                 pRoot->FirstChildElement("interface");
7638e31778eSAsmitha Karunanithi 
7648e31778eSAsmitha Karunanithi             bool isProgressIntfPresent = false;
7658e31778eSAsmitha Karunanithi             while (interfaceNode != nullptr)
7668e31778eSAsmitha Karunanithi             {
767bd79bce8SPatrick Williams                 const char* thisInterfaceName =
768bd79bce8SPatrick Williams                     interfaceNode->Attribute("name");
7698e31778eSAsmitha Karunanithi                 if (thisInterfaceName != nullptr)
7708e31778eSAsmitha Karunanithi                 {
7718e31778eSAsmitha Karunanithi                     if (thisInterfaceName ==
7728e31778eSAsmitha Karunanithi                         std::string_view("xyz.openbmc_project.Common.Progress"))
7738e31778eSAsmitha Karunanithi                     {
7748e31778eSAsmitha Karunanithi                         interfaceNode =
7758e31778eSAsmitha Karunanithi                             interfaceNode->NextSiblingElement("interface");
7768e31778eSAsmitha Karunanithi                         continue;
7778e31778eSAsmitha Karunanithi                     }
7788e31778eSAsmitha Karunanithi                     isProgressIntfPresent = true;
7798e31778eSAsmitha Karunanithi                     break;
7808e31778eSAsmitha Karunanithi                 }
7818e31778eSAsmitha Karunanithi                 interfaceNode = interfaceNode->NextSiblingElement("interface");
7828e31778eSAsmitha Karunanithi             }
7838e31778eSAsmitha Karunanithi 
784a43be80fSAsmitha Karunanithi             std::shared_ptr<task::TaskData> task = task::TaskData::createTask(
7858e31778eSAsmitha Karunanithi                 [createdObjPath, dumpEntryPath, dumpId, isProgressIntfPresent](
786bd79bce8SPatrick Williams                     const boost::system::error_code& ec2,
787bd79bce8SPatrick Williams                     sdbusplus::message_t& msg,
788a43be80fSAsmitha Karunanithi                     const std::shared_ptr<task::TaskData>& taskData) {
7898b24275dSEd Tanous                     if (ec2)
790cb13a392SEd Tanous                     {
79162598e31SEd Tanous                         BMCWEB_LOG_ERROR("{}: Error in creating dump",
79262598e31SEd Tanous                                          createdObjPath.str);
793bd79bce8SPatrick Williams                         taskData->messages.emplace_back(
794bd79bce8SPatrick Williams                             messages::internalError());
7956145ed6fSAsmitha Karunanithi                         taskData->state = "Cancelled";
7966145ed6fSAsmitha Karunanithi                         return task::completed;
797cb13a392SEd Tanous                     }
798b9d36b47SEd Tanous 
7998e31778eSAsmitha Karunanithi                     if (isProgressIntfPresent)
800a43be80fSAsmitha Karunanithi                     {
8018e31778eSAsmitha Karunanithi                         dbus::utility::DBusPropertiesMap values;
8028e31778eSAsmitha Karunanithi                         std::string prop;
8038e31778eSAsmitha Karunanithi                         msg.read(prop, values);
8048e31778eSAsmitha Karunanithi 
8058e31778eSAsmitha Karunanithi                         DumpCreationProgress dumpStatus =
8068e31778eSAsmitha Karunanithi                             getDumpCompletionStatus(values);
807bd79bce8SPatrick Williams                         if (dumpStatus ==
808bd79bce8SPatrick Williams                             DumpCreationProgress::DUMP_CREATE_FAILED)
8098e31778eSAsmitha Karunanithi                         {
81062598e31SEd Tanous                             BMCWEB_LOG_ERROR("{}: Error in creating dump",
81162598e31SEd Tanous                                              createdObjPath.str);
8128e31778eSAsmitha Karunanithi                             taskData->state = "Cancelled";
8138e31778eSAsmitha Karunanithi                             return task::completed;
8148e31778eSAsmitha Karunanithi                         }
8158e31778eSAsmitha Karunanithi 
816bd79bce8SPatrick Williams                         if (dumpStatus ==
817bd79bce8SPatrick Williams                             DumpCreationProgress::DUMP_CREATE_INPROGRESS)
8188e31778eSAsmitha Karunanithi                         {
819bd79bce8SPatrick Williams                             BMCWEB_LOG_DEBUG(
820bd79bce8SPatrick Williams                                 "{}: Dump creation task is in progress",
82162598e31SEd Tanous                                 createdObjPath.str);
8228e31778eSAsmitha Karunanithi                             return !task::completed;
8238e31778eSAsmitha Karunanithi                         }
8248e31778eSAsmitha Karunanithi                     }
8258e31778eSAsmitha Karunanithi 
826a43be80fSAsmitha Karunanithi                     nlohmann::json retMessage = messages::success();
827a43be80fSAsmitha Karunanithi                     taskData->messages.emplace_back(retMessage);
828a43be80fSAsmitha Karunanithi 
829c51a58eeSEd Tanous                     boost::urls::url url = boost::urls::format(
830253f11b8SEd Tanous                         "/redfish/v1/Managers/{}/LogServices/Dump/Entries/{}",
831253f11b8SEd Tanous                         BMCWEB_REDFISH_MANAGER_URI_NAME, dumpId);
832c51a58eeSEd Tanous 
833c51a58eeSEd Tanous                     std::string headerLoc = "Location: ";
834c51a58eeSEd Tanous                     headerLoc += url.buffer();
835c51a58eeSEd Tanous 
836bd79bce8SPatrick Williams                     taskData->payload->httpHeaders.emplace_back(
837bd79bce8SPatrick Williams                         std::move(headerLoc));
838a43be80fSAsmitha Karunanithi 
83962598e31SEd Tanous                     BMCWEB_LOG_DEBUG("{}: Dump creation task completed",
84062598e31SEd Tanous                                      createdObjPath.str);
841a43be80fSAsmitha Karunanithi                     taskData->state = "Completed";
842b47452b2SAsmitha Karunanithi                     return task::completed;
843a43be80fSAsmitha Karunanithi                 },
8448e31778eSAsmitha Karunanithi                 "type='signal',interface='org.freedesktop.DBus.Properties',"
8458e31778eSAsmitha Karunanithi                 "member='PropertiesChanged',path='" +
8468e31778eSAsmitha Karunanithi                     createdObjPath.str + "'");
847a43be80fSAsmitha Karunanithi 
8488e31778eSAsmitha Karunanithi             // The task timer is set to max time limit within which the
8498e31778eSAsmitha Karunanithi             // requested dump will be collected.
8508e31778eSAsmitha Karunanithi             task->startTimer(std::chrono::minutes(6));
8518e31778eSAsmitha Karunanithi             task->payload.emplace(payload);
85229e2bdd7SChinmay Shripad Hegde             task->populateResp(asyncResp->res);
8538e31778eSAsmitha Karunanithi         },
8548e31778eSAsmitha Karunanithi         "xyz.openbmc_project.Dump.Manager", createdObjPath,
8558e31778eSAsmitha Karunanithi         "org.freedesktop.DBus.Introspectable", "Introspect");
856a43be80fSAsmitha Karunanithi }
857a43be80fSAsmitha Karunanithi 
8588d1b46d7Szhanghch05 inline void createDump(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
8598d1b46d7Szhanghch05                        const crow::Request& req, const std::string& dumpType)
860a43be80fSAsmitha Karunanithi {
861fdd26906SClaire Weinan     std::string dumpPath = getDumpEntriesPath(dumpType);
862fdd26906SClaire Weinan     if (dumpPath.empty())
863a43be80fSAsmitha Karunanithi     {
864a43be80fSAsmitha Karunanithi         messages::internalError(asyncResp->res);
865a43be80fSAsmitha Karunanithi         return;
866a43be80fSAsmitha Karunanithi     }
867a43be80fSAsmitha Karunanithi 
868a43be80fSAsmitha Karunanithi     std::optional<std::string> diagnosticDataType;
869a43be80fSAsmitha Karunanithi     std::optional<std::string> oemDiagnosticDataType;
870a43be80fSAsmitha Karunanithi 
871afc474aeSMyung Bae     if (!redfish::json_util::readJsonAction(               //
872afc474aeSMyung Bae             req, asyncResp->res,                           //
873afc474aeSMyung Bae             "DiagnosticDataType", diagnosticDataType,      //
874afc474aeSMyung Bae             "OEMDiagnosticDataType", oemDiagnosticDataType //
875afc474aeSMyung Bae             ))
876a43be80fSAsmitha Karunanithi     {
877a43be80fSAsmitha Karunanithi         return;
878a43be80fSAsmitha Karunanithi     }
879a43be80fSAsmitha Karunanithi 
880a43be80fSAsmitha Karunanithi     if (dumpType == "System")
881a43be80fSAsmitha Karunanithi     {
882a43be80fSAsmitha Karunanithi         if (!oemDiagnosticDataType || !diagnosticDataType)
883a43be80fSAsmitha Karunanithi         {
88462598e31SEd Tanous             BMCWEB_LOG_ERROR(
88562598e31SEd Tanous                 "CreateDump action parameter 'DiagnosticDataType'/'OEMDiagnosticDataType' value not found!");
886a43be80fSAsmitha Karunanithi             messages::actionParameterMissing(
887a43be80fSAsmitha Karunanithi                 asyncResp->res, "CollectDiagnosticData",
888a43be80fSAsmitha Karunanithi                 "DiagnosticDataType & OEMDiagnosticDataType");
889a43be80fSAsmitha Karunanithi             return;
890a43be80fSAsmitha Karunanithi         }
8913174e4dfSEd Tanous         if ((*oemDiagnosticDataType != "System") ||
892a43be80fSAsmitha Karunanithi             (*diagnosticDataType != "OEM"))
893a43be80fSAsmitha Karunanithi         {
89462598e31SEd Tanous             BMCWEB_LOG_ERROR("Wrong parameter values passed");
895ace85d60SEd Tanous             messages::internalError(asyncResp->res);
896a43be80fSAsmitha Karunanithi             return;
897a43be80fSAsmitha Karunanithi         }
898253f11b8SEd Tanous         dumpPath = std::format("/redfish/v1/Systems/{}/LogServices/Dump/",
899253f11b8SEd Tanous                                BMCWEB_REDFISH_SYSTEM_URI_NAME);
900a43be80fSAsmitha Karunanithi     }
901a43be80fSAsmitha Karunanithi     else if (dumpType == "BMC")
902a43be80fSAsmitha Karunanithi     {
903a43be80fSAsmitha Karunanithi         if (!diagnosticDataType)
904a43be80fSAsmitha Karunanithi         {
90562598e31SEd Tanous             BMCWEB_LOG_ERROR(
90662598e31SEd Tanous                 "CreateDump action parameter 'DiagnosticDataType' not found!");
907a43be80fSAsmitha Karunanithi             messages::actionParameterMissing(
908a43be80fSAsmitha Karunanithi                 asyncResp->res, "CollectDiagnosticData", "DiagnosticDataType");
909a43be80fSAsmitha Karunanithi             return;
910a43be80fSAsmitha Karunanithi         }
9113174e4dfSEd Tanous         if (*diagnosticDataType != "Manager")
912a43be80fSAsmitha Karunanithi         {
91362598e31SEd Tanous             BMCWEB_LOG_ERROR(
91462598e31SEd Tanous                 "Wrong parameter value passed for 'DiagnosticDataType'");
915ace85d60SEd Tanous             messages::internalError(asyncResp->res);
916a43be80fSAsmitha Karunanithi             return;
917a43be80fSAsmitha Karunanithi         }
918253f11b8SEd Tanous         dumpPath = std::format("/redfish/v1/Managers/{}/LogServices/Dump/",
919253f11b8SEd Tanous                                BMCWEB_REDFISH_MANAGER_URI_NAME);
9205907571dSAsmitha Karunanithi     }
9215907571dSAsmitha Karunanithi     else
9225907571dSAsmitha Karunanithi     {
92362598e31SEd Tanous         BMCWEB_LOG_ERROR("CreateDump failed. Unknown dump type");
9245907571dSAsmitha Karunanithi         messages::internalError(asyncResp->res);
9255907571dSAsmitha Karunanithi         return;
926a43be80fSAsmitha Karunanithi     }
927a43be80fSAsmitha Karunanithi 
9288e31778eSAsmitha Karunanithi     std::vector<std::pair<std::string, std::variant<std::string, uint64_t>>>
9298e31778eSAsmitha Karunanithi         createDumpParamVec;
9308e31778eSAsmitha Karunanithi 
931f574a8e1SCarson Labrado     if (req.session != nullptr)
932f574a8e1SCarson Labrado     {
93368dd075aSAsmitha Karunanithi         createDumpParamVec.emplace_back(
93468dd075aSAsmitha Karunanithi             "xyz.openbmc_project.Dump.Create.CreateParameters.OriginatorId",
93568dd075aSAsmitha Karunanithi             req.session->clientIp);
93668dd075aSAsmitha Karunanithi         createDumpParamVec.emplace_back(
93768dd075aSAsmitha Karunanithi             "xyz.openbmc_project.Dump.Create.CreateParameters.OriginatorType",
93868dd075aSAsmitha Karunanithi             "xyz.openbmc_project.Common.OriginatedBy.OriginatorTypes.Client");
939f574a8e1SCarson Labrado     }
94068dd075aSAsmitha Karunanithi 
941177612aaSEd Tanous     dbus::utility::async_method_call(
942177612aaSEd Tanous         asyncResp,
9435e7e2dc5SEd Tanous         [asyncResp, payload(task::Payload(req)),
9445e7e2dc5SEd Tanous          dumpPath](const boost::system::error_code& ec,
9455e7e2dc5SEd Tanous                    const sdbusplus::message_t& msg,
9468e31778eSAsmitha Karunanithi                    const sdbusplus::message::object_path& objPath) mutable {
947a43be80fSAsmitha Karunanithi             if (ec)
948a43be80fSAsmitha Karunanithi             {
94962598e31SEd Tanous                 BMCWEB_LOG_ERROR("CreateDump resp_handler got error {}", ec);
9505907571dSAsmitha Karunanithi                 const sd_bus_error* dbusError = msg.get_error();
9515907571dSAsmitha Karunanithi                 if (dbusError == nullptr)
9525907571dSAsmitha Karunanithi                 {
9535907571dSAsmitha Karunanithi                     messages::internalError(asyncResp->res);
9545907571dSAsmitha Karunanithi                     return;
9555907571dSAsmitha Karunanithi                 }
9565907571dSAsmitha Karunanithi 
95762598e31SEd Tanous                 BMCWEB_LOG_ERROR("CreateDump DBus error: {} and error msg: {}",
95862598e31SEd Tanous                                  dbusError->name, dbusError->message);
9595907571dSAsmitha Karunanithi                 if (std::string_view(
9605907571dSAsmitha Karunanithi                         "xyz.openbmc_project.Common.Error.NotAllowed") ==
9615907571dSAsmitha Karunanithi                     dbusError->name)
9625907571dSAsmitha Karunanithi                 {
9635907571dSAsmitha Karunanithi                     messages::resourceInStandby(asyncResp->res);
9645907571dSAsmitha Karunanithi                     return;
9655907571dSAsmitha Karunanithi                 }
9665907571dSAsmitha Karunanithi                 if (std::string_view(
9675907571dSAsmitha Karunanithi                         "xyz.openbmc_project.Dump.Create.Error.Disabled") ==
9685907571dSAsmitha Karunanithi                     dbusError->name)
9695907571dSAsmitha Karunanithi                 {
9705907571dSAsmitha Karunanithi                     messages::serviceDisabled(asyncResp->res, dumpPath);
9715907571dSAsmitha Karunanithi                     return;
9725907571dSAsmitha Karunanithi                 }
9735907571dSAsmitha Karunanithi                 if (std::string_view(
9745907571dSAsmitha Karunanithi                         "xyz.openbmc_project.Common.Error.Unavailable") ==
9755907571dSAsmitha Karunanithi                     dbusError->name)
9765907571dSAsmitha Karunanithi                 {
9775907571dSAsmitha Karunanithi                     messages::resourceInUse(asyncResp->res);
9785907571dSAsmitha Karunanithi                     return;
9795907571dSAsmitha Karunanithi                 }
9805907571dSAsmitha Karunanithi                 // Other Dbus errors such as:
9815907571dSAsmitha Karunanithi                 // xyz.openbmc_project.Common.Error.InvalidArgument &
9825907571dSAsmitha Karunanithi                 // org.freedesktop.DBus.Error.InvalidArgs are all related to
9835907571dSAsmitha Karunanithi                 // the dbus call that is made here in the bmcweb
9845907571dSAsmitha Karunanithi                 // implementation and has nothing to do with the client's
9855907571dSAsmitha Karunanithi                 // input in the request. Hence, returning internal error
9865907571dSAsmitha Karunanithi                 // back to the client.
987a43be80fSAsmitha Karunanithi                 messages::internalError(asyncResp->res);
988a43be80fSAsmitha Karunanithi                 return;
989a43be80fSAsmitha Karunanithi             }
99062598e31SEd Tanous             BMCWEB_LOG_DEBUG("Dump Created. Path: {}", objPath.str);
9918e31778eSAsmitha Karunanithi             createDumpTaskCallback(std::move(payload), asyncResp, objPath);
992a43be80fSAsmitha Karunanithi         },
99318f8f608SEd Tanous         "xyz.openbmc_project.Dump.Manager", getDumpPath(dumpType),
9948e31778eSAsmitha Karunanithi         "xyz.openbmc_project.Dump.Create", "CreateDump", createDumpParamVec);
995a43be80fSAsmitha Karunanithi }
996a43be80fSAsmitha Karunanithi 
9978d1b46d7Szhanghch05 inline void clearDump(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
9988d1b46d7Szhanghch05                       const std::string& dumpType)
99980319af1SAsmitha Karunanithi {
1000177612aaSEd Tanous     dbus::utility::async_method_call(
1001177612aaSEd Tanous         asyncResp,
10020d946211SClaire Weinan         [asyncResp](const boost::system::error_code& ec) {
100380319af1SAsmitha Karunanithi             if (ec)
100480319af1SAsmitha Karunanithi             {
100562598e31SEd Tanous                 BMCWEB_LOG_ERROR("clearDump resp_handler got error {}", ec);
100680319af1SAsmitha Karunanithi                 messages::internalError(asyncResp->res);
100780319af1SAsmitha Karunanithi                 return;
100880319af1SAsmitha Karunanithi             }
1009e2460466SAmy Chang             messages::success(asyncResp->res);
10100d946211SClaire Weinan         },
101118f8f608SEd Tanous         "xyz.openbmc_project.Dump.Manager", getDumpPath(dumpType),
10120d946211SClaire Weinan         "xyz.openbmc_project.Collection.DeleteAll", "DeleteAll");
101380319af1SAsmitha Karunanithi }
101480319af1SAsmitha Karunanithi 
1015bd79bce8SPatrick Williams inline void parseCrashdumpParameters(
1016bd79bce8SPatrick Williams     const dbus::utility::DBusPropertiesMap& params, std::string& filename,
1017bd79bce8SPatrick Williams     std::string& timestamp, std::string& logfile)
1018043a0536SJohnathan Mantey {
1019d1bde9e5SKrzysztof Grobelny     const std::string* filenamePtr = nullptr;
1020d1bde9e5SKrzysztof Grobelny     const std::string* timestampPtr = nullptr;
1021d1bde9e5SKrzysztof Grobelny     const std::string* logfilePtr = nullptr;
1022d1bde9e5SKrzysztof Grobelny 
1023d1bde9e5SKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
1024d1bde9e5SKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), params, "Timestamp", timestampPtr,
1025d1bde9e5SKrzysztof Grobelny         "Filename", filenamePtr, "Log", logfilePtr);
1026d1bde9e5SKrzysztof Grobelny 
1027d1bde9e5SKrzysztof Grobelny     if (!success)
1028043a0536SJohnathan Mantey     {
1029d1bde9e5SKrzysztof Grobelny         return;
1030043a0536SJohnathan Mantey     }
1031d1bde9e5SKrzysztof Grobelny 
1032d1bde9e5SKrzysztof Grobelny     if (filenamePtr != nullptr)
1033043a0536SJohnathan Mantey     {
1034d1bde9e5SKrzysztof Grobelny         filename = *filenamePtr;
1035d1bde9e5SKrzysztof Grobelny     }
1036d1bde9e5SKrzysztof Grobelny 
1037d1bde9e5SKrzysztof Grobelny     if (timestampPtr != nullptr)
1038043a0536SJohnathan Mantey     {
1039d1bde9e5SKrzysztof Grobelny         timestamp = *timestampPtr;
1040043a0536SJohnathan Mantey     }
1041d1bde9e5SKrzysztof Grobelny 
1042d1bde9e5SKrzysztof Grobelny     if (logfilePtr != nullptr)
1043043a0536SJohnathan Mantey     {
1044d1bde9e5SKrzysztof Grobelny         logfile = *logfilePtr;
1045043a0536SJohnathan Mantey     }
1046043a0536SJohnathan Mantey }
1047043a0536SJohnathan Mantey 
10487e860f15SJohn Edward Broadbent inline void requestRoutesSystemLogServiceCollection(App& app)
10491da66f75SEd Tanous {
1050c4bf6374SJason M. Bills     /**
1051c4bf6374SJason M. Bills      * Functions triggers appropriate requests on DBus
1052c4bf6374SJason M. Bills      */
105322d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/")
1054ed398213SEd Tanous         .privileges(redfish::privileges::getLogServiceCollection)
1055bd79bce8SPatrick Williams         .methods(
1056bd79bce8SPatrick Williams             boost::beast::http::verb::
1057bd79bce8SPatrick Williams                 get)([&app](const crow::Request& req,
105822d268cbSEd Tanous                             const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
105922d268cbSEd Tanous                             const std::string& systemName) {
10603ba00073SCarson Labrado             if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1061c4bf6374SJason M. Bills             {
106245ca1b86SEd Tanous                 return;
106345ca1b86SEd Tanous             }
106425b54dbaSEd Tanous             if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
10657f3e84a1SEd Tanous             {
10667f3e84a1SEd Tanous                 // Option currently returns no systems.  TBD
10677f3e84a1SEd Tanous                 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
10687f3e84a1SEd Tanous                                            systemName);
10697f3e84a1SEd Tanous                 return;
10707f3e84a1SEd Tanous             }
1071253f11b8SEd Tanous             if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
107222d268cbSEd Tanous             {
107322d268cbSEd Tanous                 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
107422d268cbSEd Tanous                                            systemName);
107522d268cbSEd Tanous                 return;
107622d268cbSEd Tanous             }
107722d268cbSEd Tanous 
10787e860f15SJohn Edward Broadbent             // Collections don't include the static data added by SubRoute
10797e860f15SJohn Edward Broadbent             // because it has a duplicate entry for members
1080c4bf6374SJason M. Bills             asyncResp->res.jsonValue["@odata.type"] =
1081c4bf6374SJason M. Bills                 "#LogServiceCollection.LogServiceCollection";
1082c4bf6374SJason M. Bills             asyncResp->res.jsonValue["@odata.id"] =
1083253f11b8SEd Tanous                 std::format("/redfish/v1/Systems/{}/LogServices",
1084253f11b8SEd Tanous                             BMCWEB_REDFISH_SYSTEM_URI_NAME);
108545ca1b86SEd Tanous             asyncResp->res.jsonValue["Name"] = "System Log Services Collection";
1086c4bf6374SJason M. Bills             asyncResp->res.jsonValue["Description"] =
1087c4bf6374SJason M. Bills                 "Collection of LogServices for this Computer System";
1088bd79bce8SPatrick Williams             nlohmann::json& logServiceArray =
1089bd79bce8SPatrick Williams                 asyncResp->res.jsonValue["Members"];
1090c4bf6374SJason M. Bills             logServiceArray = nlohmann::json::array();
10911476687dSEd Tanous             nlohmann::json::object_t eventLog;
10921476687dSEd Tanous             eventLog["@odata.id"] =
1093253f11b8SEd Tanous                 std::format("/redfish/v1/Systems/{}/LogServices/EventLog",
1094253f11b8SEd Tanous                             BMCWEB_REDFISH_SYSTEM_URI_NAME);
1095b2ba3072SPatrick Williams             logServiceArray.emplace_back(std::move(eventLog));
109625b54dbaSEd Tanous             if constexpr (BMCWEB_REDFISH_DUMP_LOG)
109725b54dbaSEd Tanous             {
10981476687dSEd Tanous                 nlohmann::json::object_t dumpLog;
109925b54dbaSEd Tanous                 dumpLog["@odata.id"] =
1100253f11b8SEd Tanous                     std::format("/redfish/v1/Systems/{}/LogServices/Dump",
1101253f11b8SEd Tanous                                 BMCWEB_REDFISH_SYSTEM_URI_NAME);
1102b2ba3072SPatrick Williams                 logServiceArray.emplace_back(std::move(dumpLog));
110325b54dbaSEd Tanous             }
1104c9bb6861Sraviteja-b 
11055ffd11f2SGunnar Mills             if constexpr (BMCWEB_REDFISH_CPU_LOG)
110625b54dbaSEd Tanous             {
11071476687dSEd Tanous                 nlohmann::json::object_t crashdump;
11081476687dSEd Tanous                 crashdump["@odata.id"] =
1109253f11b8SEd Tanous                     std::format("/redfish/v1/Systems/{}/LogServices/Crashdump",
1110253f11b8SEd Tanous                                 BMCWEB_REDFISH_SYSTEM_URI_NAME);
1111b2ba3072SPatrick Williams                 logServiceArray.emplace_back(std::move(crashdump));
111225b54dbaSEd Tanous             }
1113b7028ebfSSpencer Ku 
111425b54dbaSEd Tanous             if constexpr (BMCWEB_REDFISH_HOST_LOGGER)
111525b54dbaSEd Tanous             {
11161476687dSEd Tanous                 nlohmann::json::object_t hostlogger;
11171476687dSEd Tanous                 hostlogger["@odata.id"] =
1118253f11b8SEd Tanous                     std::format("/redfish/v1/Systems/{}/LogServices/HostLogger",
1119253f11b8SEd Tanous                                 BMCWEB_REDFISH_SYSTEM_URI_NAME);
1120b2ba3072SPatrick Williams                 logServiceArray.emplace_back(std::move(hostlogger));
112125b54dbaSEd Tanous             }
1122c4bf6374SJason M. Bills             asyncResp->res.jsonValue["Members@odata.count"] =
1123c4bf6374SJason M. Bills                 logServiceArray.size();
1124a3316fc6SZhikuiRen 
11257a1dbc48SGeorge Liu             constexpr std::array<std::string_view, 1> interfaces = {
11267a1dbc48SGeorge Liu                 "xyz.openbmc_project.State.Boot.PostCode"};
11277a1dbc48SGeorge Liu             dbus::utility::getSubTreePaths(
11287a1dbc48SGeorge Liu                 "/", 0, interfaces,
11297a1dbc48SGeorge Liu                 [asyncResp](const boost::system::error_code& ec,
1130b9d36b47SEd Tanous                             const dbus::utility::MapperGetSubTreePathsResponse&
1131b9d36b47SEd Tanous                                 subtreePath) {
1132a3316fc6SZhikuiRen                     if (ec)
1133a3316fc6SZhikuiRen                     {
113462598e31SEd Tanous                         BMCWEB_LOG_ERROR("{}", ec);
1135a3316fc6SZhikuiRen                         return;
1136a3316fc6SZhikuiRen                     }
1137a3316fc6SZhikuiRen 
113855f79e6fSEd Tanous                     for (const auto& pathStr : subtreePath)
1139a3316fc6SZhikuiRen                     {
1140a3316fc6SZhikuiRen                         if (pathStr.find("PostCode") != std::string::npos)
1141a3316fc6SZhikuiRen                         {
114223a21a1cSEd Tanous                             nlohmann::json& logServiceArrayLocal =
1143a3316fc6SZhikuiRen                                 asyncResp->res.jsonValue["Members"];
1144613dabeaSEd Tanous                             nlohmann::json::object_t member;
1145253f11b8SEd Tanous                             member["@odata.id"] = std::format(
1146253f11b8SEd Tanous                                 "/redfish/v1/Systems/{}/LogServices/PostCodes",
1147253f11b8SEd Tanous                                 BMCWEB_REDFISH_SYSTEM_URI_NAME);
1148613dabeaSEd Tanous 
1149bd79bce8SPatrick Williams                             logServiceArrayLocal.emplace_back(
1150bd79bce8SPatrick Williams                                 std::move(member));
1151613dabeaSEd Tanous 
115245ca1b86SEd Tanous                             asyncResp->res.jsonValue["Members@odata.count"] =
115323a21a1cSEd Tanous                                 logServiceArrayLocal.size();
1154a3316fc6SZhikuiRen                             return;
1155a3316fc6SZhikuiRen                         }
1156a3316fc6SZhikuiRen                     }
11577a1dbc48SGeorge Liu                 });
11587e860f15SJohn Edward Broadbent         });
1159c4bf6374SJason M. Bills }
1160c4bf6374SJason M. Bills 
11617e860f15SJohn Edward Broadbent inline void requestRoutesEventLogService(App& app)
1162c4bf6374SJason M. Bills {
116322d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/EventLog/")
1164ed398213SEd Tanous         .privileges(redfish::privileges::getLogService)
1165bd79bce8SPatrick Williams         .methods(
1166bd79bce8SPatrick Williams             boost::beast::http::verb::
1167bd79bce8SPatrick Williams                 get)([&app](const crow::Request& req,
116822d268cbSEd Tanous                             const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
116922d268cbSEd Tanous                             const std::string& systemName) {
11703ba00073SCarson Labrado             if (!redfish::setUpRedfishRoute(app, req, asyncResp))
117145ca1b86SEd Tanous             {
117245ca1b86SEd Tanous                 return;
117345ca1b86SEd Tanous             }
1174253f11b8SEd Tanous             if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
117522d268cbSEd Tanous             {
117622d268cbSEd Tanous                 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
117722d268cbSEd Tanous                                            systemName);
117822d268cbSEd Tanous                 return;
117922d268cbSEd Tanous             }
1180c4bf6374SJason M. Bills             asyncResp->res.jsonValue["@odata.id"] =
1181253f11b8SEd Tanous                 std::format("/redfish/v1/Systems/{}/LogServices/EventLog",
1182253f11b8SEd Tanous                             BMCWEB_REDFISH_SYSTEM_URI_NAME);
1183c4bf6374SJason M. Bills             asyncResp->res.jsonValue["@odata.type"] =
1184b25644a1SJanet Adkins                 "#LogService.v1_2_0.LogService";
1185c4bf6374SJason M. Bills             asyncResp->res.jsonValue["Name"] = "Event Log Service";
1186bd79bce8SPatrick Williams             asyncResp->res.jsonValue["Description"] =
1187bd79bce8SPatrick Williams                 "System Event Log Service";
1188c4bf6374SJason M. Bills             asyncResp->res.jsonValue["Id"] = "EventLog";
1189539d8c6bSEd Tanous             asyncResp->res.jsonValue["OverWritePolicy"] =
1190539d8c6bSEd Tanous                 log_service::OverWritePolicy::WrapsWhenFull;
11917c8c4058STejas Patil 
11927c8c4058STejas Patil             std::pair<std::string, std::string> redfishDateTimeOffset =
11932b82937eSEd Tanous                 redfish::time_utils::getDateTimeOffsetNow();
11947c8c4058STejas Patil 
11957c8c4058STejas Patil             asyncResp->res.jsonValue["DateTime"] = redfishDateTimeOffset.first;
11967c8c4058STejas Patil             asyncResp->res.jsonValue["DateTimeLocalOffset"] =
11977c8c4058STejas Patil                 redfishDateTimeOffset.second;
11987c8c4058STejas Patil 
1199bd79bce8SPatrick Williams             asyncResp->res.jsonValue["Entries"]["@odata.id"] = std::format(
1200bd79bce8SPatrick Williams                 "/redfish/v1/Systems/{}/LogServices/EventLog/Entries",
1201253f11b8SEd Tanous                 BMCWEB_REDFISH_SYSTEM_URI_NAME);
1202bd79bce8SPatrick Williams             asyncResp->res
1203bd79bce8SPatrick Williams                 .jsonValue["Actions"]["#LogService.ClearLog"]["target"]
1204e7d6c8b2SGunnar Mills 
120520fa6a2cSEd Tanous                 = std::format(
1206253f11b8SEd Tanous                     "/redfish/v1/Systems/{}/LogServices/EventLog/Actions/LogService.ClearLog",
120720fa6a2cSEd Tanous                     BMCWEB_REDFISH_SYSTEM_URI_NAME);
12087e860f15SJohn Edward Broadbent         });
1209489640c6SJason M. Bills }
1210489640c6SJason M. Bills 
1211599b9af3SAlexander Hansen inline void handleSystemsLogServicesEventLogActionsClearPost(
1212599b9af3SAlexander Hansen     App& app, const crow::Request& req,
121322d268cbSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1214599b9af3SAlexander Hansen     const std::string& systemName)
1215599b9af3SAlexander Hansen {
12163ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
121745ca1b86SEd Tanous     {
121845ca1b86SEd Tanous         return;
121945ca1b86SEd Tanous     }
1220253f11b8SEd Tanous     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
122122d268cbSEd Tanous     {
122222d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
122322d268cbSEd Tanous                                    systemName);
122422d268cbSEd Tanous         return;
122522d268cbSEd Tanous     }
1226599b9af3SAlexander Hansen 
1227489640c6SJason M. Bills     // Clear the EventLog by deleting the log files
1228489640c6SJason M. Bills     std::vector<std::filesystem::path> redfishLogFiles;
1229489640c6SJason M. Bills     if (getRedfishLogFiles(redfishLogFiles))
1230489640c6SJason M. Bills     {
1231489640c6SJason M. Bills         for (const std::filesystem::path& file : redfishLogFiles)
1232489640c6SJason M. Bills         {
1233489640c6SJason M. Bills             std::error_code ec;
1234489640c6SJason M. Bills             std::filesystem::remove(file, ec);
1235489640c6SJason M. Bills         }
1236489640c6SJason M. Bills     }
1237489640c6SJason M. Bills 
1238489640c6SJason M. Bills     // Reload rsyslog so it knows to start new log files
1239177612aaSEd Tanous     dbus::utility::async_method_call(
1240177612aaSEd Tanous         asyncResp,
12415e7e2dc5SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
1242489640c6SJason M. Bills             if (ec)
1243489640c6SJason M. Bills             {
124462598e31SEd Tanous                 BMCWEB_LOG_ERROR("Failed to reload rsyslog: {}", ec);
1245489640c6SJason M. Bills                 messages::internalError(asyncResp->res);
1246489640c6SJason M. Bills                 return;
1247489640c6SJason M. Bills             }
1248489640c6SJason M. Bills 
1249489640c6SJason M. Bills             messages::success(asyncResp->res);
1250489640c6SJason M. Bills         },
1251489640c6SJason M. Bills         "org.freedesktop.systemd1", "/org/freedesktop/systemd1",
1252002d39b4SEd Tanous         "org.freedesktop.systemd1.Manager", "ReloadUnit", "rsyslog.service",
1253002d39b4SEd Tanous         "replace");
1254599b9af3SAlexander Hansen }
1255599b9af3SAlexander Hansen 
1256599b9af3SAlexander Hansen inline void requestRoutesJournalEventLogClear(App& app)
1257599b9af3SAlexander Hansen {
1258599b9af3SAlexander Hansen     BMCWEB_ROUTE(
1259599b9af3SAlexander Hansen         app,
1260599b9af3SAlexander Hansen         "/redfish/v1/Systems/<str>/LogServices/EventLog/Actions/LogService.ClearLog/")
1261fff6a4d3SAbhishek Patel         .privileges(redfish::privileges::
1262fff6a4d3SAbhishek Patel                         postLogServiceSubOverComputerSystemLogServiceCollection)
1263599b9af3SAlexander Hansen         .methods(boost::beast::http::verb::post)(std::bind_front(
1264599b9af3SAlexander Hansen             handleSystemsLogServicesEventLogActionsClearPost, std::ref(app)));
1265c4bf6374SJason M. Bills }
1266c4bf6374SJason M. Bills 
1267ac992cdeSJason M. Bills enum class LogParseError
1268ac992cdeSJason M. Bills {
1269ac992cdeSJason M. Bills     success,
1270ac992cdeSJason M. Bills     parseFailed,
1271ac992cdeSJason M. Bills     messageIdNotInRegistry,
1272ac992cdeSJason M. Bills };
1273ac992cdeSJason M. Bills 
1274bd79bce8SPatrick Williams static LogParseError fillEventLogEntryJson(
1275bd79bce8SPatrick Williams     const std::string& logEntryID, const std::string& logEntry,
1276de703c5dSJason M. Bills     nlohmann::json::object_t& logEntryJson)
1277c4bf6374SJason M. Bills {
127895820184SJason M. Bills     // The redfish log format is "<Timestamp> <MessageId>,<MessageArgs>"
1279cd225da8SJason M. Bills     // First get the Timestamp
1280f23b7296SEd Tanous     size_t space = logEntry.find_first_of(' ');
1281cd225da8SJason M. Bills     if (space == std::string::npos)
128295820184SJason M. Bills     {
1283ac992cdeSJason M. Bills         return LogParseError::parseFailed;
128495820184SJason M. Bills     }
1285cd225da8SJason M. Bills     std::string timestamp = logEntry.substr(0, space);
1286cd225da8SJason M. Bills     // Then get the log contents
1287f23b7296SEd Tanous     size_t entryStart = logEntry.find_first_not_of(' ', space);
1288cd225da8SJason M. Bills     if (entryStart == std::string::npos)
1289cd225da8SJason M. Bills     {
1290ac992cdeSJason M. Bills         return LogParseError::parseFailed;
1291cd225da8SJason M. Bills     }
1292cd225da8SJason M. Bills     std::string_view entry(logEntry);
1293cd225da8SJason M. Bills     entry.remove_prefix(entryStart);
1294cd225da8SJason M. Bills     // Use split to separate the entry into its fields
1295cd225da8SJason M. Bills     std::vector<std::string> logEntryFields;
129650ebd4afSEd Tanous     bmcweb::split(logEntryFields, entry, ',');
1297cd225da8SJason M. Bills     // We need at least a MessageId to be valid
12981e6deaf6SEd Tanous     auto logEntryIter = logEntryFields.begin();
12991e6deaf6SEd Tanous     if (logEntryIter == logEntryFields.end())
1300cd225da8SJason M. Bills     {
1301ac992cdeSJason M. Bills         return LogParseError::parseFailed;
1302cd225da8SJason M. Bills     }
13031e6deaf6SEd Tanous     std::string& messageID = *logEntryIter;
13044851d45dSJason M. Bills     // Get the Message from the MessageRegistry
1305fffb8c1fSEd Tanous     const registries::Message* message = registries::getMessage(messageID);
1306c4bf6374SJason M. Bills 
13071e6deaf6SEd Tanous     logEntryIter++;
130854417b02SSui Chen     if (message == nullptr)
1309c4bf6374SJason M. Bills     {
131062598e31SEd Tanous         BMCWEB_LOG_WARNING("Log entry not found in registry: {}", logEntry);
1311ac992cdeSJason M. Bills         return LogParseError::messageIdNotInRegistry;
1312c4bf6374SJason M. Bills     }
1313c4bf6374SJason M. Bills 
13141e6deaf6SEd Tanous     std::vector<std::string_view> messageArgs(logEntryIter,
13151e6deaf6SEd Tanous                                               logEntryFields.end());
1316c05bba45SEd Tanous     messageArgs.resize(message->numberOfArgs);
1317c05bba45SEd Tanous 
1318bd79bce8SPatrick Williams     std::string msg =
1319bd79bce8SPatrick Williams         redfish::registries::fillMessageArgs(messageArgs, message->message);
13201e6deaf6SEd Tanous     if (msg.empty())
132115a86ff6SJason M. Bills     {
13221e6deaf6SEd Tanous         return LogParseError::parseFailed;
132315a86ff6SJason M. Bills     }
13244851d45dSJason M. Bills 
132595820184SJason M. Bills     // Get the Created time from the timestamp. The log timestamp is in RFC3339
132695820184SJason M. Bills     // format which matches the Redfish format except for the fractional seconds
132795820184SJason M. Bills     // between the '.' and the '+', so just remove them.
1328f23b7296SEd Tanous     std::size_t dot = timestamp.find_first_of('.');
1329f23b7296SEd Tanous     std::size_t plus = timestamp.find_first_of('+');
133095820184SJason M. Bills     if (dot != std::string::npos && plus != std::string::npos)
1331c4bf6374SJason M. Bills     {
133295820184SJason M. Bills         timestamp.erase(dot, plus - dot);
1333c4bf6374SJason M. Bills     }
1334c4bf6374SJason M. Bills 
1335c4bf6374SJason M. Bills     // Fill in the log entry with the gathered data
13369c11a172SVijay Lobo     logEntryJson["@odata.type"] = "#LogEntry.v1_9_0.LogEntry";
1337ef4c65b7SEd Tanous     logEntryJson["@odata.id"] = boost::urls::format(
1338253f11b8SEd Tanous         "/redfish/v1/Systems/{}/LogServices/EventLog/Entries/{}",
1339253f11b8SEd Tanous         BMCWEB_REDFISH_SYSTEM_URI_NAME, logEntryID);
134084afc48bSJason M. Bills     logEntryJson["Name"] = "System Event Log Entry";
134184afc48bSJason M. Bills     logEntryJson["Id"] = logEntryID;
134284afc48bSJason M. Bills     logEntryJson["Message"] = std::move(msg);
134384afc48bSJason M. Bills     logEntryJson["MessageId"] = std::move(messageID);
134484afc48bSJason M. Bills     logEntryJson["MessageArgs"] = messageArgs;
134584afc48bSJason M. Bills     logEntryJson["EntryType"] = "Event";
134684afc48bSJason M. Bills     logEntryJson["Severity"] = message->messageSeverity;
134784afc48bSJason M. Bills     logEntryJson["Created"] = std::move(timestamp);
1348ac992cdeSJason M. Bills     return LogParseError::success;
1349c4bf6374SJason M. Bills }
1350c4bf6374SJason M. Bills 
13517f3726a2SMyung Bae inline void fillEventLogLogEntryFromDbusLogEntry(
13527f3726a2SMyung Bae     const DbusEventLogEntry& entry, nlohmann::json& objectToFillOut)
1353898f2aa2SEd Tanous {
1354898f2aa2SEd Tanous     objectToFillOut["@odata.type"] = "#LogEntry.v1_9_0.LogEntry";
1355898f2aa2SEd Tanous     objectToFillOut["@odata.id"] = boost::urls::format(
1356898f2aa2SEd Tanous         "/redfish/v1/Systems/{}/LogServices/EventLog/Entries/{}",
1357262dcc1cSAlexander Hansen         BMCWEB_REDFISH_SYSTEM_URI_NAME, std::to_string(entry.Id));
1358898f2aa2SEd Tanous     objectToFillOut["Name"] = "System Event Log Entry";
1359262dcc1cSAlexander Hansen     objectToFillOut["Id"] = std::to_string(entry.Id);
1360262dcc1cSAlexander Hansen     objectToFillOut["Message"] = entry.Message;
1361262dcc1cSAlexander Hansen     objectToFillOut["Resolved"] = entry.Resolved;
1362262dcc1cSAlexander Hansen     std::optional<bool> notifyAction =
1363262dcc1cSAlexander Hansen         getProviderNotifyAction(entry.ServiceProviderNotify);
1364898f2aa2SEd Tanous     if (notifyAction)
1365898f2aa2SEd Tanous     {
1366898f2aa2SEd Tanous         objectToFillOut["ServiceProviderNotified"] = *notifyAction;
1367898f2aa2SEd Tanous     }
1368262dcc1cSAlexander Hansen     if ((entry.Resolution != nullptr) && !entry.Resolution->empty())
1369898f2aa2SEd Tanous     {
1370262dcc1cSAlexander Hansen         objectToFillOut["Resolution"] = *entry.Resolution;
1371898f2aa2SEd Tanous     }
1372898f2aa2SEd Tanous     objectToFillOut["EntryType"] = "Event";
1373262dcc1cSAlexander Hansen     objectToFillOut["Severity"] =
1374262dcc1cSAlexander Hansen         translateSeverityDbusToRedfish(entry.Severity);
1375898f2aa2SEd Tanous     objectToFillOut["Created"] =
1376262dcc1cSAlexander Hansen         redfish::time_utils::getDateTimeUintMs(entry.Timestamp);
1377898f2aa2SEd Tanous     objectToFillOut["Modified"] =
1378262dcc1cSAlexander Hansen         redfish::time_utils::getDateTimeUintMs(entry.UpdateTimestamp);
1379262dcc1cSAlexander Hansen     if (entry.Path != nullptr)
1380898f2aa2SEd Tanous     {
1381898f2aa2SEd Tanous         objectToFillOut["AdditionalDataURI"] = boost::urls::format(
1382898f2aa2SEd Tanous             "/redfish/v1/Systems/{}/LogServices/EventLog/Entries/{}/attachment",
1383262dcc1cSAlexander Hansen             BMCWEB_REDFISH_SYSTEM_URI_NAME, std::to_string(entry.Id));
1384898f2aa2SEd Tanous     }
1385898f2aa2SEd Tanous }
1386898f2aa2SEd Tanous 
1387b729096dSEd Tanous inline void afterLogEntriesGetManagedObjects(
1388b729096dSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1389b729096dSEd Tanous     const boost::system::error_code& ec,
1390b729096dSEd Tanous     const dbus::utility::ManagedObjectType& resp)
1391b729096dSEd Tanous {
1392b729096dSEd Tanous     if (ec)
1393b729096dSEd Tanous     {
1394b729096dSEd Tanous         // TODO Handle for specific error code
1395b729096dSEd Tanous         BMCWEB_LOG_ERROR("getLogEntriesIfaceData resp_handler got error {}",
1396b729096dSEd Tanous                          ec);
1397b729096dSEd Tanous         messages::internalError(asyncResp->res);
1398b729096dSEd Tanous         return;
1399b729096dSEd Tanous     }
1400b729096dSEd Tanous     nlohmann::json::array_t entriesArray;
1401b729096dSEd Tanous     for (const auto& objectPath : resp)
1402b729096dSEd Tanous     {
1403898f2aa2SEd Tanous         dbus::utility::DBusPropertiesMap propsFlattened;
1404bd79bce8SPatrick Williams         auto isEntry =
1405bd79bce8SPatrick Williams             std::ranges::find_if(objectPath.second, [](const auto& object) {
1406898f2aa2SEd Tanous                 return object.first == "xyz.openbmc_project.Logging.Entry";
1407898f2aa2SEd Tanous             });
1408898f2aa2SEd Tanous         if (isEntry == objectPath.second.end())
1409b729096dSEd Tanous         {
1410b729096dSEd Tanous             continue;
1411b729096dSEd Tanous         }
14127f3726a2SMyung Bae 
1413898f2aa2SEd Tanous         for (const auto& interfaceMap : objectPath.second)
1414b729096dSEd Tanous         {
1415898f2aa2SEd Tanous             for (const auto& propertyMap : interfaceMap.second)
1416b729096dSEd Tanous             {
1417898f2aa2SEd Tanous                 propsFlattened.emplace_back(propertyMap.first,
1418898f2aa2SEd Tanous                                             propertyMap.second);
1419b729096dSEd Tanous             }
1420b729096dSEd Tanous         }
14217f3726a2SMyung Bae         std::optional<DbusEventLogEntry> optEntry =
14227f3726a2SMyung Bae             fillDbusEventLogEntryFromPropertyMap(propsFlattened);
14237f3726a2SMyung Bae 
14247f3726a2SMyung Bae         if (!optEntry.has_value())
142590896601SIgor Kanyuka         {
14267f3726a2SMyung Bae             messages::internalError(asyncResp->res);
142790896601SIgor Kanyuka             return;
142890896601SIgor Kanyuka         }
14297f3726a2SMyung Bae         fillEventLogLogEntryFromDbusLogEntry(*optEntry,
14307f3726a2SMyung Bae                                              entriesArray.emplace_back());
1431b729096dSEd Tanous     }
1432898f2aa2SEd Tanous 
143390896601SIgor Kanyuka     redfish::json_util::sortJsonArrayByKey(entriesArray, "Id");
1434b729096dSEd Tanous     asyncResp->res.jsonValue["Members@odata.count"] = entriesArray.size();
1435b729096dSEd Tanous     asyncResp->res.jsonValue["Members"] = std::move(entriesArray);
1436b729096dSEd Tanous }
1437b729096dSEd Tanous 
1438599b9af3SAlexander Hansen inline void handleSystemsLogServiceEventLogLogEntryCollection(
1439599b9af3SAlexander Hansen     App& app, const crow::Request& req,
144022d268cbSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1441599b9af3SAlexander Hansen     const std::string& systemName)
1442599b9af3SAlexander Hansen {
1443c937d2bfSEd Tanous     query_param::QueryCapabilities capabilities = {
1444c937d2bfSEd Tanous         .canDelegateTop = true,
1445c937d2bfSEd Tanous         .canDelegateSkip = true,
1446c937d2bfSEd Tanous     };
1447c937d2bfSEd Tanous     query_param::Query delegatedQuery;
1448599b9af3SAlexander Hansen     if (!redfish::setUpRedfishRouteWithDelegation(app, req, asyncResp,
1449599b9af3SAlexander Hansen                                                   delegatedQuery, capabilities))
1450c4bf6374SJason M. Bills     {
1451c4bf6374SJason M. Bills         return;
1452c4bf6374SJason M. Bills     }
145325b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
14547f3e84a1SEd Tanous     {
14557f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
14567f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
14577f3e84a1SEd Tanous                                    systemName);
14587f3e84a1SEd Tanous         return;
14597f3e84a1SEd Tanous     }
1460253f11b8SEd Tanous     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
146122d268cbSEd Tanous     {
146222d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
146322d268cbSEd Tanous                                    systemName);
146422d268cbSEd Tanous         return;
146522d268cbSEd Tanous     }
146622d268cbSEd Tanous 
14675143f7a5SJiaqing Zhao     size_t top = delegatedQuery.top.value_or(query_param::Query::maxTop);
14683648c8beSEd Tanous     size_t skip = delegatedQuery.skip.value_or(0);
14693648c8beSEd Tanous 
14707e860f15SJohn Edward Broadbent     // Collections don't include the static data added by SubRoute
14717e860f15SJohn Edward Broadbent     // because it has a duplicate entry for members
1472c4bf6374SJason M. Bills     asyncResp->res.jsonValue["@odata.type"] =
1473c4bf6374SJason M. Bills         "#LogEntryCollection.LogEntryCollection";
1474c4bf6374SJason M. Bills     asyncResp->res.jsonValue["@odata.id"] =
1475253f11b8SEd Tanous         std::format("/redfish/v1/Systems/{}/LogServices/EventLog/Entries",
1476253f11b8SEd Tanous                     BMCWEB_REDFISH_SYSTEM_URI_NAME);
1477c4bf6374SJason M. Bills     asyncResp->res.jsonValue["Name"] = "System Event Log Entries";
1478c4bf6374SJason M. Bills     asyncResp->res.jsonValue["Description"] =
1479c4bf6374SJason M. Bills         "Collection of System Event Log Entries";
1480cb92c03bSAndrew Geissler 
14814978b63fSJason M. Bills     nlohmann::json& logEntryArray = asyncResp->res.jsonValue["Members"];
1482c4bf6374SJason M. Bills     logEntryArray = nlohmann::json::array();
14837e860f15SJohn Edward Broadbent     // Go through the log files and create a unique ID for each
14847e860f15SJohn Edward Broadbent     // entry
148595820184SJason M. Bills     std::vector<std::filesystem::path> redfishLogFiles;
148695820184SJason M. Bills     getRedfishLogFiles(redfishLogFiles);
1487b01bf299SEd Tanous     uint64_t entryCount = 0;
1488cd225da8SJason M. Bills     std::string logEntry;
148995820184SJason M. Bills 
14907e860f15SJohn Edward Broadbent     // Oldest logs are in the last file, so start there and loop
14917e860f15SJohn Edward Broadbent     // backwards
1492599b9af3SAlexander Hansen     for (auto it = redfishLogFiles.rbegin(); it < redfishLogFiles.rend(); it++)
1493c4bf6374SJason M. Bills     {
1494cd225da8SJason M. Bills         std::ifstream logStream(*it);
149595820184SJason M. Bills         if (!logStream.is_open())
1496c4bf6374SJason M. Bills         {
1497c4bf6374SJason M. Bills             continue;
1498c4bf6374SJason M. Bills         }
1499c4bf6374SJason M. Bills 
1500e85d6b16SJason M. Bills         // Reset the unique ID on the first entry
1501e85d6b16SJason M. Bills         bool firstEntry = true;
150295820184SJason M. Bills         while (std::getline(logStream, logEntry))
150395820184SJason M. Bills         {
1504c4bf6374SJason M. Bills             std::string idStr;
1505e85d6b16SJason M. Bills             if (!getUniqueEntryID(logEntry, idStr, firstEntry))
1506c4bf6374SJason M. Bills             {
1507c4bf6374SJason M. Bills                 continue;
1508c4bf6374SJason M. Bills             }
1509e85d6b16SJason M. Bills             firstEntry = false;
1510e85d6b16SJason M. Bills 
1511de703c5dSJason M. Bills             nlohmann::json::object_t bmcLogEntry;
1512bd79bce8SPatrick Williams             LogParseError status =
1513bd79bce8SPatrick Williams                 fillEventLogEntryJson(idStr, logEntry, bmcLogEntry);
1514ac992cdeSJason M. Bills             if (status == LogParseError::messageIdNotInRegistry)
1515ac992cdeSJason M. Bills             {
1516ac992cdeSJason M. Bills                 continue;
1517ac992cdeSJason M. Bills             }
1518ac992cdeSJason M. Bills             if (status != LogParseError::success)
1519c4bf6374SJason M. Bills             {
1520c4bf6374SJason M. Bills                 messages::internalError(asyncResp->res);
1521c4bf6374SJason M. Bills                 return;
1522c4bf6374SJason M. Bills             }
1523de703c5dSJason M. Bills 
1524de703c5dSJason M. Bills             entryCount++;
1525de703c5dSJason M. Bills             // Handle paging using skip (number of entries to skip from the
1526de703c5dSJason M. Bills             // start) and top (number of entries to display)
15273648c8beSEd Tanous             if (entryCount <= skip || entryCount > skip + top)
1528de703c5dSJason M. Bills             {
1529de703c5dSJason M. Bills                 continue;
1530de703c5dSJason M. Bills             }
1531de703c5dSJason M. Bills 
1532b2ba3072SPatrick Williams             logEntryArray.emplace_back(std::move(bmcLogEntry));
1533c4bf6374SJason M. Bills         }
153495820184SJason M. Bills     }
1535c4bf6374SJason M. Bills     asyncResp->res.jsonValue["Members@odata.count"] = entryCount;
15363648c8beSEd Tanous     if (skip + top < entryCount)
1537c4bf6374SJason M. Bills     {
1538599b9af3SAlexander Hansen         asyncResp->res.jsonValue["Members@odata.nextLink"] =
1539599b9af3SAlexander Hansen             boost::urls::format(
1540253f11b8SEd Tanous                 "/redfish/v1/Systems/{}/LogServices/EventLog/Entries?$skip={}",
1541253f11b8SEd Tanous                 BMCWEB_REDFISH_SYSTEM_URI_NAME, std::to_string(skip + top));
1542c4bf6374SJason M. Bills     }
1543897967deSJason M. Bills }
1544897967deSJason M. Bills 
1545599b9af3SAlexander Hansen inline void requestRoutesJournalEventLogEntryCollection(App& app)
1546897967deSJason M. Bills {
1547599b9af3SAlexander Hansen     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/")
1548599b9af3SAlexander Hansen         .privileges(redfish::privileges::getLogEntryCollection)
1549599b9af3SAlexander Hansen         .methods(boost::beast::http::verb::get)(std::bind_front(
1550599b9af3SAlexander Hansen             handleSystemsLogServiceEventLogLogEntryCollection, std::ref(app)));
1551599b9af3SAlexander Hansen }
1552599b9af3SAlexander Hansen 
1553599b9af3SAlexander Hansen inline void handleSystemsLogServiceEventLogEntriesGet(
1554599b9af3SAlexander Hansen     App& app, const crow::Request& req,
15557e860f15SJohn Edward Broadbent     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1556599b9af3SAlexander Hansen     const std::string& systemName, const std::string& param)
1557599b9af3SAlexander Hansen {
15583ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
155945ca1b86SEd Tanous     {
156045ca1b86SEd Tanous         return;
156145ca1b86SEd Tanous     }
156225b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
15637f3e84a1SEd Tanous     {
15647f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
15657f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
15667f3e84a1SEd Tanous                                    systemName);
15677f3e84a1SEd Tanous         return;
15687f3e84a1SEd Tanous     }
156922d268cbSEd Tanous 
1570253f11b8SEd Tanous     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
157122d268cbSEd Tanous     {
157222d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
157322d268cbSEd Tanous                                    systemName);
157422d268cbSEd Tanous         return;
157522d268cbSEd Tanous     }
157622d268cbSEd Tanous 
15777e860f15SJohn Edward Broadbent     const std::string& targetID = param;
15788d1b46d7Szhanghch05 
15797e860f15SJohn Edward Broadbent     // Go through the log files and check the unique ID for each
15807e860f15SJohn Edward Broadbent     // entry to find the target entry
1581897967deSJason M. Bills     std::vector<std::filesystem::path> redfishLogFiles;
1582897967deSJason M. Bills     getRedfishLogFiles(redfishLogFiles);
1583897967deSJason M. Bills     std::string logEntry;
1584897967deSJason M. Bills 
15857e860f15SJohn Edward Broadbent     // Oldest logs are in the last file, so start there and loop
15867e860f15SJohn Edward Broadbent     // backwards
1587599b9af3SAlexander Hansen     for (auto it = redfishLogFiles.rbegin(); it < redfishLogFiles.rend(); it++)
1588897967deSJason M. Bills     {
1589897967deSJason M. Bills         std::ifstream logStream(*it);
1590897967deSJason M. Bills         if (!logStream.is_open())
1591897967deSJason M. Bills         {
1592897967deSJason M. Bills             continue;
1593897967deSJason M. Bills         }
1594897967deSJason M. Bills 
1595897967deSJason M. Bills         // Reset the unique ID on the first entry
1596897967deSJason M. Bills         bool firstEntry = true;
1597897967deSJason M. Bills         while (std::getline(logStream, logEntry))
1598897967deSJason M. Bills         {
1599897967deSJason M. Bills             std::string idStr;
1600897967deSJason M. Bills             if (!getUniqueEntryID(logEntry, idStr, firstEntry))
1601897967deSJason M. Bills             {
1602897967deSJason M. Bills                 continue;
1603897967deSJason M. Bills             }
1604897967deSJason M. Bills             firstEntry = false;
1605897967deSJason M. Bills 
1606897967deSJason M. Bills             if (idStr == targetID)
1607897967deSJason M. Bills             {
1608de703c5dSJason M. Bills                 nlohmann::json::object_t bmcLogEntry;
1609bd79bce8SPatrick Williams                 LogParseError status =
1610bd79bce8SPatrick Williams                     fillEventLogEntryJson(idStr, logEntry, bmcLogEntry);
1611ac992cdeSJason M. Bills                 if (status != LogParseError::success)
1612897967deSJason M. Bills                 {
1613897967deSJason M. Bills                     messages::internalError(asyncResp->res);
1614897967deSJason M. Bills                     return;
1615897967deSJason M. Bills                 }
1616d405bb51SJason M. Bills                 asyncResp->res.jsonValue.update(bmcLogEntry);
1617897967deSJason M. Bills                 return;
1618897967deSJason M. Bills             }
1619897967deSJason M. Bills         }
1620897967deSJason M. Bills     }
1621897967deSJason M. Bills     // Requested ID was not found
16229db4ba25SJiaqing Zhao     messages::resourceNotFound(asyncResp->res, "LogEntry", targetID);
1623599b9af3SAlexander Hansen }
1624599b9af3SAlexander Hansen 
1625599b9af3SAlexander Hansen inline void requestRoutesJournalEventLogEntry(App& app)
1626599b9af3SAlexander Hansen {
1627599b9af3SAlexander Hansen     BMCWEB_ROUTE(
1628599b9af3SAlexander Hansen         app, "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/<str>/")
1629599b9af3SAlexander Hansen         .privileges(redfish::privileges::getLogEntry)
1630599b9af3SAlexander Hansen         .methods(boost::beast::http::verb::get)(std::bind_front(
1631599b9af3SAlexander Hansen             handleSystemsLogServiceEventLogEntriesGet, std::ref(app)));
1632599b9af3SAlexander Hansen }
1633599b9af3SAlexander Hansen 
1634599b9af3SAlexander Hansen inline void dBusEventLogEntryCollection(
1635599b9af3SAlexander Hansen     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1636599b9af3SAlexander Hansen {
1637599b9af3SAlexander Hansen     // Collections don't include the static data added by SubRoute
1638599b9af3SAlexander Hansen     // because it has a duplicate entry for members
1639599b9af3SAlexander Hansen     asyncResp->res.jsonValue["@odata.type"] =
1640599b9af3SAlexander Hansen         "#LogEntryCollection.LogEntryCollection";
1641599b9af3SAlexander Hansen     asyncResp->res.jsonValue["@odata.id"] =
1642599b9af3SAlexander Hansen         std::format("/redfish/v1/Systems/{}/LogServices/EventLog/Entries",
1643599b9af3SAlexander Hansen                     BMCWEB_REDFISH_SYSTEM_URI_NAME);
1644599b9af3SAlexander Hansen     asyncResp->res.jsonValue["Name"] = "System Event Log Entries";
1645599b9af3SAlexander Hansen     asyncResp->res.jsonValue["Description"] =
1646599b9af3SAlexander Hansen         "Collection of System Event Log Entries";
1647599b9af3SAlexander Hansen 
1648599b9af3SAlexander Hansen     // DBus implementation of EventLog/Entries
1649599b9af3SAlexander Hansen     // Make call to Logging Service to find all log entry objects
1650599b9af3SAlexander Hansen     sdbusplus::message::object_path path("/xyz/openbmc_project/logging");
1651599b9af3SAlexander Hansen     dbus::utility::getManagedObjects(
1652599b9af3SAlexander Hansen         "xyz.openbmc_project.Logging", path,
1653599b9af3SAlexander Hansen         [asyncResp](const boost::system::error_code& ec,
1654599b9af3SAlexander Hansen                     const dbus::utility::ManagedObjectType& resp) {
1655b729096dSEd Tanous             afterLogEntriesGetManagedObjects(asyncResp, ec, resp);
16567e860f15SJohn Edward Broadbent         });
165708a4e4b5SAnthony Wilson }
165808a4e4b5SAnthony Wilson 
16597e860f15SJohn Edward Broadbent inline void requestRoutesDBusEventLogEntryCollection(App& app)
166008a4e4b5SAnthony Wilson {
166122d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/")
1662ed398213SEd Tanous         .privileges(redfish::privileges::getLogEntryCollection)
1663002d39b4SEd Tanous         .methods(boost::beast::http::verb::get)(
1664002d39b4SEd Tanous             [&app](const crow::Request& req,
166522d268cbSEd Tanous                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
166622d268cbSEd Tanous                    const std::string& systemName) {
16673ba00073SCarson Labrado                 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
166845ca1b86SEd Tanous                 {
166945ca1b86SEd Tanous                     return;
167045ca1b86SEd Tanous                 }
167125b54dbaSEd Tanous                 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
16727f3e84a1SEd Tanous                 {
16737f3e84a1SEd Tanous                     // Option currently returns no systems.  TBD
16747f3e84a1SEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
16757f3e84a1SEd Tanous                                                systemName);
16767f3e84a1SEd Tanous                     return;
16777f3e84a1SEd Tanous                 }
1678253f11b8SEd Tanous                 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
167922d268cbSEd Tanous                 {
168022d268cbSEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
168122d268cbSEd Tanous                                                systemName);
168222d268cbSEd Tanous                     return;
168322d268cbSEd Tanous                 }
1684599b9af3SAlexander Hansen                 dBusEventLogEntryCollection(asyncResp);
1685599b9af3SAlexander Hansen             });
1686599b9af3SAlexander Hansen }
168722d268cbSEd Tanous 
1688c6b7cae2SMyung Bae inline void afterDBusEventLogEntryGet(
1689c6b7cae2SMyung Bae     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1690c6b7cae2SMyung Bae     const std::string& entryID, const boost::system::error_code& ec,
1691c6b7cae2SMyung Bae     const dbus::utility::DBusPropertiesMap& resp)
1692c6b7cae2SMyung Bae {
1693c6b7cae2SMyung Bae     if (ec.value() == EBADR)
1694c6b7cae2SMyung Bae     {
1695c6b7cae2SMyung Bae         messages::resourceNotFound(asyncResp->res, "EventLogEntry", entryID);
1696c6b7cae2SMyung Bae         return;
1697c6b7cae2SMyung Bae     }
1698c6b7cae2SMyung Bae     if (ec)
1699c6b7cae2SMyung Bae     {
1700c6b7cae2SMyung Bae         BMCWEB_LOG_ERROR("EventLogEntry (DBus) resp_handler got error {}", ec);
1701c6b7cae2SMyung Bae         messages::internalError(asyncResp->res);
1702c6b7cae2SMyung Bae         return;
1703c6b7cae2SMyung Bae     }
1704c6b7cae2SMyung Bae 
17057f3726a2SMyung Bae     std::optional<DbusEventLogEntry> optEntry =
17067f3726a2SMyung Bae         fillDbusEventLogEntryFromPropertyMap(resp);
17077f3726a2SMyung Bae 
17087f3726a2SMyung Bae     if (!optEntry.has_value())
17097f3726a2SMyung Bae     {
17107f3726a2SMyung Bae         messages::internalError(asyncResp->res);
17117f3726a2SMyung Bae         return;
17127f3726a2SMyung Bae     }
17137f3726a2SMyung Bae 
17147f3726a2SMyung Bae     fillEventLogLogEntryFromDbusLogEntry(*optEntry, asyncResp->res.jsonValue);
1715c6b7cae2SMyung Bae }
1716c6b7cae2SMyung Bae 
1717bd79bce8SPatrick Williams inline void dBusEventLogEntryGet(
1718bd79bce8SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, std::string entryID)
1719599b9af3SAlexander Hansen {
1720599b9af3SAlexander Hansen     dbus::utility::escapePathForDbus(entryID);
172108a4e4b5SAnthony Wilson 
1722cb92c03bSAndrew Geissler     // DBus implementation of EventLog/Entries
1723cb92c03bSAndrew Geissler     // Make call to Logging Service to find all log entry objects
1724deae6a78SEd Tanous     dbus::utility::getAllProperties(
1725deae6a78SEd Tanous         "xyz.openbmc_project.Logging",
1726599b9af3SAlexander Hansen         "/xyz/openbmc_project/logging/entry/" + entryID, "",
1727c6b7cae2SMyung Bae         std::bind_front(afterDBusEventLogEntryGet, asyncResp, entryID));
17287e860f15SJohn Edward Broadbent }
1729599b9af3SAlexander Hansen 
1730504af5a0SPatrick Williams inline void dBusEventLogEntryPatch(
1731504af5a0SPatrick Williams     const crow::Request& req,
1732599b9af3SAlexander Hansen     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1733599b9af3SAlexander Hansen     const std::string& entryId)
1734599b9af3SAlexander Hansen {
1735599b9af3SAlexander Hansen     std::optional<bool> resolved;
1736599b9af3SAlexander Hansen 
1737599b9af3SAlexander Hansen     if (!json_util::readJsonPatch(req, asyncResp->res, "Resolved", resolved))
1738599b9af3SAlexander Hansen     {
1739599b9af3SAlexander Hansen         return;
1740599b9af3SAlexander Hansen     }
1741599b9af3SAlexander Hansen     BMCWEB_LOG_DEBUG("Set Resolved");
1742599b9af3SAlexander Hansen 
1743599b9af3SAlexander Hansen     setDbusProperty(asyncResp, "Resolved", "xyz.openbmc_project.Logging",
1744599b9af3SAlexander Hansen                     "/xyz/openbmc_project/logging/entry/" + entryId,
1745599b9af3SAlexander Hansen                     "xyz.openbmc_project.Logging.Entry", "Resolved",
1746599b9af3SAlexander Hansen                     resolved.value_or(false));
1747599b9af3SAlexander Hansen }
1748599b9af3SAlexander Hansen 
1749bd79bce8SPatrick Williams inline void dBusEventLogEntryDelete(
1750bd79bce8SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, std::string entryID)
1751599b9af3SAlexander Hansen {
1752599b9af3SAlexander Hansen     BMCWEB_LOG_DEBUG("Do delete single event entries.");
1753599b9af3SAlexander Hansen 
1754599b9af3SAlexander Hansen     dbus::utility::escapePathForDbus(entryID);
1755599b9af3SAlexander Hansen 
1756599b9af3SAlexander Hansen     // Process response from Logging service.
1757599b9af3SAlexander Hansen     auto respHandler = [asyncResp,
1758599b9af3SAlexander Hansen                         entryID](const boost::system::error_code& ec) {
1759599b9af3SAlexander Hansen         BMCWEB_LOG_DEBUG("EventLogEntry (DBus) doDelete callback: Done");
1760599b9af3SAlexander Hansen         if (ec)
1761599b9af3SAlexander Hansen         {
1762599b9af3SAlexander Hansen             if (ec.value() == EBADR)
1763599b9af3SAlexander Hansen             {
1764599b9af3SAlexander Hansen                 messages::resourceNotFound(asyncResp->res, "LogEntry", entryID);
1765599b9af3SAlexander Hansen                 return;
1766599b9af3SAlexander Hansen             }
1767599b9af3SAlexander Hansen             // TODO Handle for specific error code
1768599b9af3SAlexander Hansen             BMCWEB_LOG_ERROR(
1769599b9af3SAlexander Hansen                 "EventLogEntry (DBus) doDelete respHandler got error {}", ec);
1770599b9af3SAlexander Hansen             asyncResp->res.result(
1771599b9af3SAlexander Hansen                 boost::beast::http::status::internal_server_error);
1772599b9af3SAlexander Hansen             return;
1773599b9af3SAlexander Hansen         }
1774599b9af3SAlexander Hansen 
1775599b9af3SAlexander Hansen         asyncResp->res.result(boost::beast::http::status::ok);
1776599b9af3SAlexander Hansen     };
1777599b9af3SAlexander Hansen 
1778599b9af3SAlexander Hansen     // Make call to Logging service to request Delete Log
1779177612aaSEd Tanous     dbus::utility::async_method_call(
1780177612aaSEd Tanous         asyncResp, respHandler, "xyz.openbmc_project.Logging",
1781599b9af3SAlexander Hansen         "/xyz/openbmc_project/logging/entry/" + entryID,
1782599b9af3SAlexander Hansen         "xyz.openbmc_project.Object.Delete", "Delete");
17837e860f15SJohn Edward Broadbent }
17847e860f15SJohn Edward Broadbent 
17857e860f15SJohn Edward Broadbent inline void requestRoutesDBusEventLogEntry(App& app)
17867e860f15SJohn Edward Broadbent {
17877e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(
178822d268cbSEd Tanous         app, "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/<str>/")
1789ed398213SEd Tanous         .privileges(redfish::privileges::getLogEntry)
1790002d39b4SEd Tanous         .methods(boost::beast::http::verb::get)(
1791002d39b4SEd Tanous             [&app](const crow::Request& req,
17927e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1793898f2aa2SEd Tanous                    const std::string& systemName, const std::string& entryId) {
17943ba00073SCarson Labrado                 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
17957e860f15SJohn Edward Broadbent                 {
179645ca1b86SEd Tanous                     return;
179745ca1b86SEd Tanous                 }
179825b54dbaSEd Tanous                 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
17997f3e84a1SEd Tanous                 {
18007f3e84a1SEd Tanous                     // Option currently returns no systems.  TBD
18017f3e84a1SEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
18027f3e84a1SEd Tanous                                                systemName);
18037f3e84a1SEd Tanous                     return;
18047f3e84a1SEd Tanous                 }
1805253f11b8SEd Tanous                 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
180622d268cbSEd Tanous                 {
180722d268cbSEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
180822d268cbSEd Tanous                                                systemName);
180922d268cbSEd Tanous                     return;
181022d268cbSEd Tanous                 }
181122d268cbSEd Tanous 
1812898f2aa2SEd Tanous                 dBusEventLogEntryGet(asyncResp, entryId);
18137e860f15SJohn Edward Broadbent             });
1814336e96c6SChicago Duan 
18157e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(
181622d268cbSEd Tanous         app, "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/<str>/")
1817ed398213SEd Tanous         .privileges(redfish::privileges::patchLogEntry)
18187e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::patch)(
181945ca1b86SEd Tanous             [&app](const crow::Request& req,
18207e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
182122d268cbSEd Tanous                    const std::string& systemName, const std::string& entryId) {
18223ba00073SCarson Labrado                 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
182345ca1b86SEd Tanous                 {
182445ca1b86SEd Tanous                     return;
182545ca1b86SEd Tanous                 }
182625b54dbaSEd Tanous                 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
18277f3e84a1SEd Tanous                 {
18287f3e84a1SEd Tanous                     // Option currently returns no systems.  TBD
18297f3e84a1SEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
18307f3e84a1SEd Tanous                                                systemName);
18317f3e84a1SEd Tanous                     return;
18327f3e84a1SEd Tanous                 }
1833253f11b8SEd Tanous                 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
183422d268cbSEd Tanous                 {
183522d268cbSEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
183622d268cbSEd Tanous                                                systemName);
183722d268cbSEd Tanous                     return;
183822d268cbSEd Tanous                 }
183975710de2SXiaochao Ma 
1840599b9af3SAlexander Hansen                 dBusEventLogEntryPatch(req, asyncResp, entryId);
18417e860f15SJohn Edward Broadbent             });
184275710de2SXiaochao Ma 
18437e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(
184422d268cbSEd Tanous         app, "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/<str>/")
1845fff6a4d3SAbhishek Patel         .privileges(
1846fff6a4d3SAbhishek Patel             redfish::privileges::
1847fff6a4d3SAbhishek Patel                 deleteLogEntrySubOverComputerSystemLogServiceCollectionLogServiceLogEntryCollection)
1848002d39b4SEd Tanous         .methods(boost::beast::http::verb::delete_)(
1849002d39b4SEd Tanous             [&app](const crow::Request& req,
1850002d39b4SEd Tanous                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
185122d268cbSEd Tanous                    const std::string& systemName, const std::string& param) {
18523ba00073SCarson Labrado                 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1853336e96c6SChicago Duan                 {
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                 }
1869599b9af3SAlexander Hansen                 dBusEventLogEntryDelete(asyncResp, param);
18707e860f15SJohn Edward Broadbent             });
1871400fd1fbSAdriana Kobylak }
1872400fd1fbSAdriana Kobylak 
1873dd72e87bSClaire Weinan inline void handleBMCLogServicesCollectionGet(
1874fdd26906SClaire Weinan     crow::App& app, const crow::Request& req,
1875253f11b8SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1876253f11b8SEd Tanous     const std::string& managerId)
18771da66f75SEd Tanous {
18783ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
187945ca1b86SEd Tanous     {
188045ca1b86SEd Tanous         return;
188145ca1b86SEd Tanous     }
1882253f11b8SEd Tanous 
1883253f11b8SEd Tanous     if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1884253f11b8SEd Tanous     {
1885253f11b8SEd Tanous         messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1886253f11b8SEd Tanous         return;
1887253f11b8SEd Tanous     }
1888253f11b8SEd Tanous 
18897e860f15SJohn Edward Broadbent     // Collections don't include the static data added by SubRoute
18907e860f15SJohn Edward Broadbent     // because it has a duplicate entry for members
1891e1f26343SJason M. Bills     asyncResp->res.jsonValue["@odata.type"] =
18921da66f75SEd Tanous         "#LogServiceCollection.LogServiceCollection";
1893253f11b8SEd Tanous     asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
1894253f11b8SEd Tanous         "/redfish/v1/Managers/{}/LogServices", BMCWEB_REDFISH_MANAGER_URI_NAME);
1895002d39b4SEd Tanous     asyncResp->res.jsonValue["Name"] = "Open BMC Log Services Collection";
1896e1f26343SJason M. Bills     asyncResp->res.jsonValue["Description"] =
18971da66f75SEd Tanous         "Collection of LogServices for this Manager";
1898002d39b4SEd Tanous     nlohmann::json& logServiceArray = asyncResp->res.jsonValue["Members"];
1899c4bf6374SJason M. Bills     logServiceArray = nlohmann::json::array();
1900fdd26906SClaire Weinan 
190125b54dbaSEd Tanous     if constexpr (BMCWEB_REDFISH_BMC_JOURNAL)
190225b54dbaSEd Tanous     {
1903613dabeaSEd Tanous         nlohmann::json::object_t journal;
1904253f11b8SEd Tanous         journal["@odata.id"] =
1905253f11b8SEd Tanous             boost::urls::format("/redfish/v1/Managers/{}/LogServices/Journal",
1906253f11b8SEd Tanous                                 BMCWEB_REDFISH_MANAGER_URI_NAME);
1907b2ba3072SPatrick Williams         logServiceArray.emplace_back(std::move(journal));
190825b54dbaSEd Tanous     }
1909fdd26906SClaire Weinan 
1910fdd26906SClaire Weinan     asyncResp->res.jsonValue["Members@odata.count"] = logServiceArray.size();
1911fdd26906SClaire Weinan 
191225b54dbaSEd Tanous     if constexpr (BMCWEB_REDFISH_DUMP_LOG)
191325b54dbaSEd Tanous     {
191415912159SGeorge Liu         constexpr std::array<std::string_view, 1> interfaces = {
19157a1dbc48SGeorge Liu             "xyz.openbmc_project.Collection.DeleteAll"};
19167a1dbc48SGeorge Liu         dbus::utility::getSubTreePaths(
19177a1dbc48SGeorge Liu             "/xyz/openbmc_project/dump", 0, interfaces,
191825b54dbaSEd Tanous             [asyncResp](const boost::system::error_code& ec,
191925b54dbaSEd Tanous                         const dbus::utility::MapperGetSubTreePathsResponse&
192025b54dbaSEd Tanous                             subTreePaths) {
1921fdd26906SClaire Weinan                 if (ec)
1922fdd26906SClaire Weinan                 {
192362598e31SEd Tanous                     BMCWEB_LOG_ERROR(
192462598e31SEd Tanous                         "handleBMCLogServicesCollectionGet respHandler got error {}",
192562598e31SEd Tanous                         ec);
1926bd79bce8SPatrick Williams                     // Assume that getting an error simply means there are no
1927bd79bce8SPatrick Williams                     // dump LogServices. Return without adding any error
1928bd79bce8SPatrick Williams                     // response.
1929fdd26906SClaire Weinan                     return;
1930fdd26906SClaire Weinan                 }
1931fdd26906SClaire Weinan 
1932fdd26906SClaire Weinan                 nlohmann::json& logServiceArrayLocal =
1933fdd26906SClaire Weinan                     asyncResp->res.jsonValue["Members"];
1934fdd26906SClaire Weinan 
1935fdd26906SClaire Weinan                 for (const std::string& path : subTreePaths)
1936fdd26906SClaire Weinan                 {
1937fdd26906SClaire Weinan                     if (path == "/xyz/openbmc_project/dump/bmc")
1938fdd26906SClaire Weinan                     {
1939613dabeaSEd Tanous                         nlohmann::json::object_t member;
1940253f11b8SEd Tanous                         member["@odata.id"] = boost::urls::format(
1941253f11b8SEd Tanous                             "/redfish/v1/Managers/{}/LogServices/Dump",
1942253f11b8SEd Tanous                             BMCWEB_REDFISH_MANAGER_URI_NAME);
1943b2ba3072SPatrick Williams                         logServiceArrayLocal.emplace_back(std::move(member));
1944fdd26906SClaire Weinan                     }
1945fdd26906SClaire Weinan                     else if (path == "/xyz/openbmc_project/dump/faultlog")
1946fdd26906SClaire Weinan                     {
1947613dabeaSEd Tanous                         nlohmann::json::object_t member;
1948253f11b8SEd Tanous                         member["@odata.id"] = boost::urls::format(
1949253f11b8SEd Tanous                             "/redfish/v1/Managers/{}/LogServices/FaultLog",
1950253f11b8SEd Tanous                             BMCWEB_REDFISH_MANAGER_URI_NAME);
1951b2ba3072SPatrick Williams                         logServiceArrayLocal.emplace_back(std::move(member));
1952fdd26906SClaire Weinan                     }
1953fdd26906SClaire Weinan                 }
1954fdd26906SClaire Weinan 
1955e1f26343SJason M. Bills                 asyncResp->res.jsonValue["Members@odata.count"] =
1956fdd26906SClaire Weinan                     logServiceArrayLocal.size();
19577a1dbc48SGeorge Liu             });
195825b54dbaSEd Tanous     }
1959fdd26906SClaire Weinan }
1960fdd26906SClaire Weinan 
1961fdd26906SClaire Weinan inline void requestRoutesBMCLogServiceCollection(App& app)
1962fdd26906SClaire Weinan {
1963253f11b8SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/LogServices/")
1964fdd26906SClaire Weinan         .privileges(redfish::privileges::getLogServiceCollection)
1965fdd26906SClaire Weinan         .methods(boost::beast::http::verb::get)(
1966dd72e87bSClaire Weinan             std::bind_front(handleBMCLogServicesCollectionGet, std::ref(app)));
1967e1f26343SJason M. Bills }
1968e1f26343SJason M. Bills 
1969504af5a0SPatrick Williams inline void getDumpServiceInfo(
1970504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1971fdd26906SClaire Weinan     const std::string& dumpType)
1972c9bb6861Sraviteja-b {
1973fdd26906SClaire Weinan     std::string dumpPath;
1974539d8c6bSEd Tanous     log_service::OverWritePolicy overWritePolicy =
1975539d8c6bSEd Tanous         log_service::OverWritePolicy::Invalid;
1976fdd26906SClaire Weinan     bool collectDiagnosticDataSupported = false;
1977fdd26906SClaire Weinan 
1978fdd26906SClaire Weinan     if (dumpType == "BMC")
197945ca1b86SEd Tanous     {
1980253f11b8SEd Tanous         dumpPath = std::format("/redfish/v1/Managers/{}/LogServices/Dump",
1981253f11b8SEd Tanous                                BMCWEB_REDFISH_MANAGER_URI_NAME);
1982539d8c6bSEd Tanous         overWritePolicy = log_service::OverWritePolicy::WrapsWhenFull;
1983fdd26906SClaire Weinan         collectDiagnosticDataSupported = true;
1984fdd26906SClaire Weinan     }
1985fdd26906SClaire Weinan     else if (dumpType == "FaultLog")
1986fdd26906SClaire Weinan     {
1987253f11b8SEd Tanous         dumpPath = std::format("/redfish/v1/Managers/{}/LogServices/FaultLog",
1988253f11b8SEd Tanous                                BMCWEB_REDFISH_MANAGER_URI_NAME);
1989539d8c6bSEd Tanous         overWritePolicy = log_service::OverWritePolicy::Unknown;
1990fdd26906SClaire Weinan         collectDiagnosticDataSupported = false;
1991fdd26906SClaire Weinan     }
1992fdd26906SClaire Weinan     else if (dumpType == "System")
1993fdd26906SClaire Weinan     {
1994253f11b8SEd Tanous         dumpPath = std::format("/redfish/v1/Systems/{}/LogServices/Dump",
1995253f11b8SEd Tanous                                BMCWEB_REDFISH_SYSTEM_URI_NAME);
1996539d8c6bSEd Tanous         overWritePolicy = log_service::OverWritePolicy::WrapsWhenFull;
1997fdd26906SClaire Weinan         collectDiagnosticDataSupported = true;
1998fdd26906SClaire Weinan     }
1999fdd26906SClaire Weinan     else
2000fdd26906SClaire Weinan     {
200162598e31SEd Tanous         BMCWEB_LOG_ERROR("getDumpServiceInfo() invalid dump type: {}",
200262598e31SEd Tanous                          dumpType);
2003fdd26906SClaire Weinan         messages::internalError(asyncResp->res);
200445ca1b86SEd Tanous         return;
200545ca1b86SEd Tanous     }
2006fdd26906SClaire Weinan 
2007fdd26906SClaire Weinan     asyncResp->res.jsonValue["@odata.id"] = dumpPath;
2008fdd26906SClaire Weinan     asyncResp->res.jsonValue["@odata.type"] = "#LogService.v1_2_0.LogService";
2009c9bb6861Sraviteja-b     asyncResp->res.jsonValue["Name"] = "Dump LogService";
2010fdd26906SClaire Weinan     asyncResp->res.jsonValue["Description"] = dumpType + " Dump LogService";
2011fdd26906SClaire Weinan     asyncResp->res.jsonValue["Id"] = std::filesystem::path(dumpPath).filename();
2012539d8c6bSEd Tanous     asyncResp->res.jsonValue["OverWritePolicy"] = overWritePolicy;
20137c8c4058STejas Patil 
20147c8c4058STejas Patil     std::pair<std::string, std::string> redfishDateTimeOffset =
20152b82937eSEd Tanous         redfish::time_utils::getDateTimeOffsetNow();
20160fda0f12SGeorge Liu     asyncResp->res.jsonValue["DateTime"] = redfishDateTimeOffset.first;
20177c8c4058STejas Patil     asyncResp->res.jsonValue["DateTimeLocalOffset"] =
20187c8c4058STejas Patil         redfishDateTimeOffset.second;
20197c8c4058STejas Patil 
2020fdd26906SClaire Weinan     asyncResp->res.jsonValue["Entries"]["@odata.id"] = dumpPath + "/Entries";
2021fdd26906SClaire Weinan 
2022fdd26906SClaire Weinan     if (collectDiagnosticDataSupported)
2023fdd26906SClaire Weinan     {
2024002d39b4SEd Tanous         asyncResp->res.jsonValue["Actions"]["#LogService.CollectDiagnosticData"]
20251476687dSEd Tanous                                 ["target"] =
2026fdd26906SClaire Weinan             dumpPath + "/Actions/LogService.CollectDiagnosticData";
2027fdd26906SClaire Weinan     }
20280d946211SClaire Weinan 
20290d946211SClaire Weinan     constexpr std::array<std::string_view, 1> interfaces = {deleteAllInterface};
20300d946211SClaire Weinan     dbus::utility::getSubTreePaths(
20310d946211SClaire Weinan         "/xyz/openbmc_project/dump", 0, interfaces,
20320d946211SClaire Weinan         [asyncResp, dumpType, dumpPath](
20330d946211SClaire Weinan             const boost::system::error_code& ec,
20340d946211SClaire Weinan             const dbus::utility::MapperGetSubTreePathsResponse& subTreePaths) {
20350d946211SClaire Weinan             if (ec)
20360d946211SClaire Weinan             {
2037bd79bce8SPatrick Williams                 BMCWEB_LOG_ERROR("getDumpServiceInfo respHandler got error {}",
2038bd79bce8SPatrick Williams                                  ec);
20390d946211SClaire Weinan                 // Assume that getting an error simply means there are no dump
20400d946211SClaire Weinan                 // LogServices. Return without adding any error response.
20410d946211SClaire Weinan                 return;
20420d946211SClaire Weinan             }
204318f8f608SEd Tanous             std::string dbusDumpPath = getDumpPath(dumpType);
20440d946211SClaire Weinan             for (const std::string& path : subTreePaths)
20450d946211SClaire Weinan             {
20460d946211SClaire Weinan                 if (path == dbusDumpPath)
20470d946211SClaire Weinan                 {
2048bd79bce8SPatrick Williams                     asyncResp->res.jsonValue["Actions"]["#LogService.ClearLog"]
2049bd79bce8SPatrick Williams                                             ["target"] =
20500d946211SClaire Weinan                         dumpPath + "/Actions/LogService.ClearLog";
20510d946211SClaire Weinan                     break;
20520d946211SClaire Weinan                 }
20530d946211SClaire Weinan             }
20540d946211SClaire Weinan         });
2055c9bb6861Sraviteja-b }
2056c9bb6861Sraviteja-b 
2057fdd26906SClaire Weinan inline void handleLogServicesDumpServiceGet(
2058fdd26906SClaire Weinan     crow::App& app, const std::string& dumpType, const crow::Request& req,
2059253f11b8SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2060253f11b8SEd Tanous     const std::string& managerId)
20617e860f15SJohn Edward Broadbent {
20623ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
206345ca1b86SEd Tanous     {
206445ca1b86SEd Tanous         return;
206545ca1b86SEd Tanous     }
2066253f11b8SEd Tanous 
2067253f11b8SEd Tanous     if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
2068253f11b8SEd Tanous     {
2069253f11b8SEd Tanous         messages::resourceNotFound(asyncResp->res, "Manager", managerId);
2070253f11b8SEd Tanous         return;
2071253f11b8SEd Tanous     }
2072253f11b8SEd Tanous 
2073fdd26906SClaire Weinan     getDumpServiceInfo(asyncResp, dumpType);
2074fdd26906SClaire Weinan }
2075c9bb6861Sraviteja-b 
207622d268cbSEd Tanous inline void handleLogServicesDumpServiceComputerSystemGet(
207722d268cbSEd Tanous     crow::App& app, const crow::Request& req,
207822d268cbSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
207922d268cbSEd Tanous     const std::string& chassisId)
208022d268cbSEd Tanous {
208122d268cbSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
208222d268cbSEd Tanous     {
208322d268cbSEd Tanous         return;
208422d268cbSEd Tanous     }
2085253f11b8SEd Tanous     if (chassisId != BMCWEB_REDFISH_SYSTEM_URI_NAME)
208622d268cbSEd Tanous     {
208722d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem", chassisId);
208822d268cbSEd Tanous         return;
208922d268cbSEd Tanous     }
209022d268cbSEd Tanous     getDumpServiceInfo(asyncResp, "System");
209122d268cbSEd Tanous }
209222d268cbSEd Tanous 
2093fdd26906SClaire Weinan inline void handleLogServicesDumpEntriesCollectionGet(
2094fdd26906SClaire Weinan     crow::App& app, const std::string& dumpType, const crow::Request& req,
2095253f11b8SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2096253f11b8SEd Tanous     const std::string& managerId)
2097fdd26906SClaire Weinan {
2098fdd26906SClaire Weinan     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2099fdd26906SClaire Weinan     {
2100fdd26906SClaire Weinan         return;
2101fdd26906SClaire Weinan     }
2102253f11b8SEd Tanous 
2103253f11b8SEd Tanous     if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
2104253f11b8SEd Tanous     {
2105253f11b8SEd Tanous         messages::resourceNotFound(asyncResp->res, "Manager", managerId);
2106253f11b8SEd Tanous         return;
2107253f11b8SEd Tanous     }
2108fdd26906SClaire Weinan     getDumpEntryCollection(asyncResp, dumpType);
2109fdd26906SClaire Weinan }
2110fdd26906SClaire Weinan 
211122d268cbSEd Tanous inline void handleLogServicesDumpEntriesCollectionComputerSystemGet(
211222d268cbSEd Tanous     crow::App& app, const crow::Request& req,
211322d268cbSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
211422d268cbSEd Tanous     const std::string& chassisId)
211522d268cbSEd Tanous {
211622d268cbSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
211722d268cbSEd Tanous     {
211822d268cbSEd Tanous         return;
211922d268cbSEd Tanous     }
2120253f11b8SEd Tanous     if (chassisId != BMCWEB_REDFISH_SYSTEM_URI_NAME)
212122d268cbSEd Tanous     {
212222d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem", chassisId);
212322d268cbSEd Tanous         return;
212422d268cbSEd Tanous     }
212522d268cbSEd Tanous     getDumpEntryCollection(asyncResp, "System");
212622d268cbSEd Tanous }
212722d268cbSEd Tanous 
2128fdd26906SClaire Weinan inline void handleLogServicesDumpEntryGet(
2129fdd26906SClaire Weinan     crow::App& app, const std::string& dumpType, const crow::Request& req,
2130fdd26906SClaire Weinan     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2131253f11b8SEd Tanous     const std::string& managerId, const std::string& dumpId)
2132fdd26906SClaire Weinan {
2133fdd26906SClaire Weinan     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2134fdd26906SClaire Weinan     {
2135fdd26906SClaire Weinan         return;
2136fdd26906SClaire Weinan     }
2137253f11b8SEd Tanous     if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
2138253f11b8SEd Tanous     {
2139253f11b8SEd Tanous         messages::resourceNotFound(asyncResp->res, "Manager", managerId);
2140253f11b8SEd Tanous         return;
2141253f11b8SEd Tanous     }
2142fdd26906SClaire Weinan     getDumpEntryById(asyncResp, dumpId, dumpType);
2143fdd26906SClaire Weinan }
2144168d1b1aSCarson Labrado 
214522d268cbSEd Tanous inline void handleLogServicesDumpEntryComputerSystemGet(
214622d268cbSEd Tanous     crow::App& app, const crow::Request& req,
214722d268cbSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
214822d268cbSEd Tanous     const std::string& chassisId, const std::string& dumpId)
214922d268cbSEd Tanous {
215022d268cbSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
215122d268cbSEd Tanous     {
215222d268cbSEd Tanous         return;
215322d268cbSEd Tanous     }
2154253f11b8SEd Tanous     if (chassisId != BMCWEB_REDFISH_SYSTEM_URI_NAME)
215522d268cbSEd Tanous     {
215622d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem", chassisId);
215722d268cbSEd Tanous         return;
215822d268cbSEd Tanous     }
215922d268cbSEd Tanous     getDumpEntryById(asyncResp, dumpId, "System");
216022d268cbSEd Tanous }
2161fdd26906SClaire Weinan 
2162fdd26906SClaire Weinan inline void handleLogServicesDumpEntryDelete(
2163fdd26906SClaire Weinan     crow::App& app, const std::string& dumpType, const crow::Request& req,
2164fdd26906SClaire Weinan     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2165253f11b8SEd Tanous     const std::string& managerId, const std::string& dumpId)
2166fdd26906SClaire Weinan {
2167fdd26906SClaire Weinan     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2168fdd26906SClaire Weinan     {
2169fdd26906SClaire Weinan         return;
2170fdd26906SClaire Weinan     }
2171253f11b8SEd Tanous 
2172253f11b8SEd Tanous     if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
2173253f11b8SEd Tanous     {
2174253f11b8SEd Tanous         messages::resourceNotFound(asyncResp->res, "Manager", managerId);
2175253f11b8SEd Tanous         return;
2176253f11b8SEd Tanous     }
2177fdd26906SClaire Weinan     deleteDumpEntry(asyncResp, dumpId, dumpType);
2178fdd26906SClaire Weinan }
2179fdd26906SClaire Weinan 
218022d268cbSEd Tanous inline void handleLogServicesDumpEntryComputerSystemDelete(
218122d268cbSEd Tanous     crow::App& app, const crow::Request& req,
218222d268cbSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
218322d268cbSEd Tanous     const std::string& chassisId, const std::string& dumpId)
218422d268cbSEd Tanous {
218522d268cbSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
218622d268cbSEd Tanous     {
218722d268cbSEd Tanous         return;
218822d268cbSEd Tanous     }
2189253f11b8SEd Tanous     if (chassisId != BMCWEB_REDFISH_SYSTEM_URI_NAME)
219022d268cbSEd Tanous     {
219122d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem", chassisId);
219222d268cbSEd Tanous         return;
219322d268cbSEd Tanous     }
219422d268cbSEd Tanous     deleteDumpEntry(asyncResp, dumpId, "System");
219522d268cbSEd Tanous }
219622d268cbSEd Tanous 
2197168d1b1aSCarson Labrado inline void handleLogServicesDumpEntryDownloadGet(
2198168d1b1aSCarson Labrado     crow::App& app, const std::string& dumpType, const crow::Request& req,
2199168d1b1aSCarson Labrado     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2200253f11b8SEd Tanous     const std::string& managerId, const std::string& dumpId)
2201168d1b1aSCarson Labrado {
2202168d1b1aSCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2203168d1b1aSCarson Labrado     {
2204168d1b1aSCarson Labrado         return;
2205168d1b1aSCarson Labrado     }
2206253f11b8SEd Tanous 
2207253f11b8SEd Tanous     if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
2208253f11b8SEd Tanous     {
2209253f11b8SEd Tanous         messages::resourceNotFound(asyncResp->res, "Manager", managerId);
2210253f11b8SEd Tanous         return;
2211253f11b8SEd Tanous     }
2212168d1b1aSCarson Labrado     downloadDumpEntry(asyncResp, dumpId, dumpType);
2213168d1b1aSCarson Labrado }
2214168d1b1aSCarson Labrado 
2215168d1b1aSCarson Labrado inline void handleDBusEventLogEntryDownloadGet(
2216168d1b1aSCarson Labrado     crow::App& app, const std::string& dumpType, const crow::Request& req,
2217168d1b1aSCarson Labrado     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2218168d1b1aSCarson Labrado     const std::string& systemName, const std::string& entryID)
2219168d1b1aSCarson Labrado {
2220168d1b1aSCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2221168d1b1aSCarson Labrado     {
2222168d1b1aSCarson Labrado         return;
2223168d1b1aSCarson Labrado     }
2224168d1b1aSCarson Labrado     if (!http_helpers::isContentTypeAllowed(
2225168d1b1aSCarson Labrado             req.getHeaderValue("Accept"),
2226168d1b1aSCarson Labrado             http_helpers::ContentType::OctetStream, true))
2227168d1b1aSCarson Labrado     {
2228168d1b1aSCarson Labrado         asyncResp->res.result(boost::beast::http::status::bad_request);
2229168d1b1aSCarson Labrado         return;
2230168d1b1aSCarson Labrado     }
2231168d1b1aSCarson Labrado     downloadEventLogEntry(asyncResp, systemName, entryID, dumpType);
2232168d1b1aSCarson Labrado }
2233168d1b1aSCarson Labrado 
2234fdd26906SClaire Weinan inline void handleLogServicesDumpCollectDiagnosticDataPost(
2235fdd26906SClaire Weinan     crow::App& app, const std::string& dumpType, const crow::Request& req,
2236253f11b8SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2237253f11b8SEd Tanous     const std::string& managerId)
2238fdd26906SClaire Weinan {
2239fdd26906SClaire Weinan     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2240fdd26906SClaire Weinan     {
2241fdd26906SClaire Weinan         return;
2242fdd26906SClaire Weinan     }
2243253f11b8SEd Tanous     if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
2244253f11b8SEd Tanous     {
2245253f11b8SEd Tanous         messages::resourceNotFound(asyncResp->res, "Manager", managerId);
2246253f11b8SEd Tanous         return;
2247253f11b8SEd Tanous     }
2248253f11b8SEd Tanous 
2249fdd26906SClaire Weinan     createDump(asyncResp, req, dumpType);
2250fdd26906SClaire Weinan }
2251fdd26906SClaire Weinan 
225222d268cbSEd Tanous inline void handleLogServicesDumpCollectDiagnosticDataComputerSystemPost(
225322d268cbSEd Tanous     crow::App& app, const crow::Request& req,
225422d268cbSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
22557f3e84a1SEd Tanous     const std::string& systemName)
225622d268cbSEd Tanous {
225722d268cbSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
225822d268cbSEd Tanous     {
225922d268cbSEd Tanous         return;
226022d268cbSEd Tanous     }
22617f3e84a1SEd Tanous 
226225b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
226322d268cbSEd Tanous     {
22647f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
22657f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
22667f3e84a1SEd Tanous                                    systemName);
22677f3e84a1SEd Tanous         return;
22687f3e84a1SEd Tanous     }
2269253f11b8SEd Tanous     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
22707f3e84a1SEd Tanous     {
22717f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
22727f3e84a1SEd Tanous                                    systemName);
227322d268cbSEd Tanous         return;
227422d268cbSEd Tanous     }
227522d268cbSEd Tanous     createDump(asyncResp, req, "System");
227622d268cbSEd Tanous }
227722d268cbSEd Tanous 
2278fdd26906SClaire Weinan inline void handleLogServicesDumpClearLogPost(
2279fdd26906SClaire Weinan     crow::App& app, const std::string& dumpType, const crow::Request& req,
2280253f11b8SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2281253f11b8SEd Tanous     const std::string& managerId)
2282fdd26906SClaire Weinan {
2283fdd26906SClaire Weinan     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2284fdd26906SClaire Weinan     {
2285fdd26906SClaire Weinan         return;
2286fdd26906SClaire Weinan     }
2287253f11b8SEd Tanous 
2288253f11b8SEd Tanous     if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
2289253f11b8SEd Tanous     {
2290253f11b8SEd Tanous         messages::resourceNotFound(asyncResp->res, "Manager", managerId);
2291253f11b8SEd Tanous         return;
2292253f11b8SEd Tanous     }
2293fdd26906SClaire Weinan     clearDump(asyncResp, dumpType);
2294fdd26906SClaire Weinan }
2295fdd26906SClaire Weinan 
229622d268cbSEd Tanous inline void handleLogServicesDumpClearLogComputerSystemPost(
229722d268cbSEd Tanous     crow::App& app, const crow::Request& req,
229822d268cbSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
22997f3e84a1SEd Tanous     const std::string& systemName)
230022d268cbSEd Tanous {
230122d268cbSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
230222d268cbSEd Tanous     {
230322d268cbSEd Tanous         return;
230422d268cbSEd Tanous     }
230525b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
230622d268cbSEd Tanous     {
23077f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
23087f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
23097f3e84a1SEd Tanous                                    systemName);
23107f3e84a1SEd Tanous         return;
23117f3e84a1SEd Tanous     }
2312253f11b8SEd Tanous     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
23137f3e84a1SEd Tanous     {
23147f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
23157f3e84a1SEd Tanous                                    systemName);
231622d268cbSEd Tanous         return;
231722d268cbSEd Tanous     }
231822d268cbSEd Tanous     clearDump(asyncResp, "System");
231922d268cbSEd Tanous }
232022d268cbSEd Tanous 
2321fdd26906SClaire Weinan inline void requestRoutesBMCDumpService(App& app)
2322fdd26906SClaire Weinan {
2323253f11b8SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/LogServices/Dump/")
2324fdd26906SClaire Weinan         .privileges(redfish::privileges::getLogService)
2325fdd26906SClaire Weinan         .methods(boost::beast::http::verb::get)(std::bind_front(
2326fdd26906SClaire Weinan             handleLogServicesDumpServiceGet, std::ref(app), "BMC"));
2327fdd26906SClaire Weinan }
2328fdd26906SClaire Weinan 
2329fdd26906SClaire Weinan inline void requestRoutesBMCDumpEntryCollection(App& app)
2330fdd26906SClaire Weinan {
2331253f11b8SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/LogServices/Dump/Entries/")
2332fdd26906SClaire Weinan         .privileges(redfish::privileges::getLogEntryCollection)
2333fdd26906SClaire Weinan         .methods(boost::beast::http::verb::get)(std::bind_front(
2334fdd26906SClaire Weinan             handleLogServicesDumpEntriesCollectionGet, std::ref(app), "BMC"));
2335c9bb6861Sraviteja-b }
2336c9bb6861Sraviteja-b 
23377e860f15SJohn Edward Broadbent inline void requestRoutesBMCDumpEntry(App& app)
2338c9bb6861Sraviteja-b {
23397e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app,
2340253f11b8SEd Tanous                  "/redfish/v1/Managers/<str>/LogServices/Dump/Entries/<str>/")
2341ed398213SEd Tanous         .privileges(redfish::privileges::getLogEntry)
2342fdd26906SClaire Weinan         .methods(boost::beast::http::verb::get)(std::bind_front(
2343fdd26906SClaire Weinan             handleLogServicesDumpEntryGet, std::ref(app), "BMC"));
2344fdd26906SClaire Weinan 
23457e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app,
2346253f11b8SEd Tanous                  "/redfish/v1/Managers/<str>/LogServices/Dump/Entries/<str>/")
2347ed398213SEd Tanous         .privileges(redfish::privileges::deleteLogEntry)
2348fdd26906SClaire Weinan         .methods(boost::beast::http::verb::delete_)(std::bind_front(
2349fdd26906SClaire Weinan             handleLogServicesDumpEntryDelete, std::ref(app), "BMC"));
2350c9bb6861Sraviteja-b }
2351c9bb6861Sraviteja-b 
2352168d1b1aSCarson Labrado inline void requestRoutesBMCDumpEntryDownload(App& app)
2353168d1b1aSCarson Labrado {
2354168d1b1aSCarson Labrado     BMCWEB_ROUTE(
2355168d1b1aSCarson Labrado         app,
2356253f11b8SEd Tanous         "/redfish/v1/Managers/<str>/LogServices/Dump/Entries/<str>/attachment/")
2357168d1b1aSCarson Labrado         .privileges(redfish::privileges::getLogEntry)
2358168d1b1aSCarson Labrado         .methods(boost::beast::http::verb::get)(std::bind_front(
2359168d1b1aSCarson Labrado             handleLogServicesDumpEntryDownloadGet, std::ref(app), "BMC"));
2360168d1b1aSCarson Labrado }
2361168d1b1aSCarson Labrado 
23627e860f15SJohn Edward Broadbent inline void requestRoutesBMCDumpCreate(App& app)
2363c9bb6861Sraviteja-b {
23640fda0f12SGeorge Liu     BMCWEB_ROUTE(
23650fda0f12SGeorge Liu         app,
2366253f11b8SEd Tanous         "/redfish/v1/Managers/<str>/LogServices/Dump/Actions/LogService.CollectDiagnosticData/")
2367ed398213SEd Tanous         .privileges(redfish::privileges::postLogService)
23687e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::post)(
2369fdd26906SClaire Weinan             std::bind_front(handleLogServicesDumpCollectDiagnosticDataPost,
2370fdd26906SClaire Weinan                             std::ref(app), "BMC"));
2371a43be80fSAsmitha Karunanithi }
2372a43be80fSAsmitha Karunanithi 
23737e860f15SJohn Edward Broadbent inline void requestRoutesBMCDumpClear(App& app)
237480319af1SAsmitha Karunanithi {
23750fda0f12SGeorge Liu     BMCWEB_ROUTE(
23760fda0f12SGeorge Liu         app,
2377253f11b8SEd Tanous         "/redfish/v1/Managers/<str>/LogServices/Dump/Actions/LogService.ClearLog/")
2378ed398213SEd Tanous         .privileges(redfish::privileges::postLogService)
2379fdd26906SClaire Weinan         .methods(boost::beast::http::verb::post)(std::bind_front(
2380fdd26906SClaire Weinan             handleLogServicesDumpClearLogPost, std::ref(app), "BMC"));
238145ca1b86SEd Tanous }
2382fdd26906SClaire Weinan 
2383168d1b1aSCarson Labrado inline void requestRoutesDBusEventLogEntryDownload(App& app)
2384168d1b1aSCarson Labrado {
2385168d1b1aSCarson Labrado     BMCWEB_ROUTE(
2386168d1b1aSCarson Labrado         app,
23879e9d99daSRavi Teja         "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/<str>/attachment/")
2388168d1b1aSCarson Labrado         .privileges(redfish::privileges::getLogEntry)
2389168d1b1aSCarson Labrado         .methods(boost::beast::http::verb::get)(std::bind_front(
2390168d1b1aSCarson Labrado             handleDBusEventLogEntryDownloadGet, std::ref(app), "System"));
2391168d1b1aSCarson Labrado }
2392168d1b1aSCarson Labrado 
2393fdd26906SClaire Weinan inline void requestRoutesFaultLogDumpService(App& app)
2394fdd26906SClaire Weinan {
2395253f11b8SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/LogServices/FaultLog/")
2396fdd26906SClaire Weinan         .privileges(redfish::privileges::getLogService)
2397fdd26906SClaire Weinan         .methods(boost::beast::http::verb::get)(std::bind_front(
2398fdd26906SClaire Weinan             handleLogServicesDumpServiceGet, std::ref(app), "FaultLog"));
2399fdd26906SClaire Weinan }
2400fdd26906SClaire Weinan 
2401fdd26906SClaire Weinan inline void requestRoutesFaultLogDumpEntryCollection(App& app)
2402fdd26906SClaire Weinan {
2403253f11b8SEd Tanous     BMCWEB_ROUTE(app,
2404253f11b8SEd Tanous                  "/redfish/v1/Managers/<str>/LogServices/FaultLog/Entries/")
2405fdd26906SClaire Weinan         .privileges(redfish::privileges::getLogEntryCollection)
2406fdd26906SClaire Weinan         .methods(boost::beast::http::verb::get)(
2407fdd26906SClaire Weinan             std::bind_front(handleLogServicesDumpEntriesCollectionGet,
2408fdd26906SClaire Weinan                             std::ref(app), "FaultLog"));
2409fdd26906SClaire Weinan }
2410fdd26906SClaire Weinan 
2411fdd26906SClaire Weinan inline void requestRoutesFaultLogDumpEntry(App& app)
2412fdd26906SClaire Weinan {
2413253f11b8SEd Tanous     BMCWEB_ROUTE(
2414253f11b8SEd Tanous         app, "/redfish/v1/Managers/<str>/LogServices/FaultLog/Entries/<str>/")
2415fdd26906SClaire Weinan         .privileges(redfish::privileges::getLogEntry)
2416fdd26906SClaire Weinan         .methods(boost::beast::http::verb::get)(std::bind_front(
2417fdd26906SClaire Weinan             handleLogServicesDumpEntryGet, std::ref(app), "FaultLog"));
2418fdd26906SClaire Weinan 
2419253f11b8SEd Tanous     BMCWEB_ROUTE(
2420253f11b8SEd Tanous         app, "/redfish/v1/Managers/<str>/LogServices/FaultLog/Entries/<str>/")
2421fdd26906SClaire Weinan         .privileges(redfish::privileges::deleteLogEntry)
2422fdd26906SClaire Weinan         .methods(boost::beast::http::verb::delete_)(std::bind_front(
2423fdd26906SClaire Weinan             handleLogServicesDumpEntryDelete, std::ref(app), "FaultLog"));
2424fdd26906SClaire Weinan }
2425fdd26906SClaire Weinan 
2426fdd26906SClaire Weinan inline void requestRoutesFaultLogDumpClear(App& app)
2427fdd26906SClaire Weinan {
2428fdd26906SClaire Weinan     BMCWEB_ROUTE(
2429fdd26906SClaire Weinan         app,
2430253f11b8SEd Tanous         "/redfish/v1/Managers/<str>/LogServices/FaultLog/Actions/LogService.ClearLog/")
2431fdd26906SClaire Weinan         .privileges(redfish::privileges::postLogService)
2432fdd26906SClaire Weinan         .methods(boost::beast::http::verb::post)(std::bind_front(
2433fdd26906SClaire Weinan             handleLogServicesDumpClearLogPost, std::ref(app), "FaultLog"));
24345cb1dd27SAsmitha Karunanithi }
24355cb1dd27SAsmitha Karunanithi 
24367e860f15SJohn Edward Broadbent inline void requestRoutesSystemDumpService(App& app)
24375cb1dd27SAsmitha Karunanithi {
243822d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/Dump/")
2439ed398213SEd Tanous         .privileges(redfish::privileges::getLogService)
24406ab9ad54SClaire Weinan         .methods(boost::beast::http::verb::get)(std::bind_front(
244122d268cbSEd Tanous             handleLogServicesDumpServiceComputerSystemGet, std::ref(app)));
24425cb1dd27SAsmitha Karunanithi }
24435cb1dd27SAsmitha Karunanithi 
24447e860f15SJohn Edward Broadbent inline void requestRoutesSystemDumpEntryCollection(App& app)
24457e860f15SJohn Edward Broadbent {
244622d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/Dump/Entries/")
2447ed398213SEd Tanous         .privileges(redfish::privileges::getLogEntryCollection)
244822d268cbSEd Tanous         .methods(boost::beast::http::verb::get)(std::bind_front(
244922d268cbSEd Tanous             handleLogServicesDumpEntriesCollectionComputerSystemGet,
245022d268cbSEd Tanous             std::ref(app)));
24515cb1dd27SAsmitha Karunanithi }
24525cb1dd27SAsmitha Karunanithi 
24537e860f15SJohn Edward Broadbent inline void requestRoutesSystemDumpEntry(App& app)
24545cb1dd27SAsmitha Karunanithi {
24557e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app,
245622d268cbSEd Tanous                  "/redfish/v1/Systems/<str>/LogServices/Dump/Entries/<str>/")
2457ed398213SEd Tanous         .privileges(redfish::privileges::getLogEntry)
24586ab9ad54SClaire Weinan         .methods(boost::beast::http::verb::get)(std::bind_front(
245922d268cbSEd Tanous             handleLogServicesDumpEntryComputerSystemGet, std::ref(app)));
24608d1b46d7Szhanghch05 
24617e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app,
246222d268cbSEd Tanous                  "/redfish/v1/Systems/<str>/LogServices/Dump/Entries/<str>/")
2463ed398213SEd Tanous         .privileges(redfish::privileges::deleteLogEntry)
24646ab9ad54SClaire Weinan         .methods(boost::beast::http::verb::delete_)(std::bind_front(
246522d268cbSEd Tanous             handleLogServicesDumpEntryComputerSystemDelete, std::ref(app)));
24665cb1dd27SAsmitha Karunanithi }
2467c9bb6861Sraviteja-b 
24687e860f15SJohn Edward Broadbent inline void requestRoutesSystemDumpCreate(App& app)
2469c9bb6861Sraviteja-b {
24700fda0f12SGeorge Liu     BMCWEB_ROUTE(
24710fda0f12SGeorge Liu         app,
247222d268cbSEd Tanous         "/redfish/v1/Systems/<str>/LogServices/Dump/Actions/LogService.CollectDiagnosticData/")
2473fff6a4d3SAbhishek Patel         .privileges(redfish::privileges::
2474fff6a4d3SAbhishek Patel                         postLogServiceSubOverComputerSystemLogServiceCollection)
247522d268cbSEd Tanous         .methods(boost::beast::http::verb::post)(std::bind_front(
247622d268cbSEd Tanous             handleLogServicesDumpCollectDiagnosticDataComputerSystemPost,
247722d268cbSEd Tanous             std::ref(app)));
2478a43be80fSAsmitha Karunanithi }
2479a43be80fSAsmitha Karunanithi 
24807e860f15SJohn Edward Broadbent inline void requestRoutesSystemDumpClear(App& app)
2481a43be80fSAsmitha Karunanithi {
24820fda0f12SGeorge Liu     BMCWEB_ROUTE(
24830fda0f12SGeorge Liu         app,
248422d268cbSEd Tanous         "/redfish/v1/Systems/<str>/LogServices/Dump/Actions/LogService.ClearLog/")
2485fff6a4d3SAbhishek Patel         .privileges(redfish::privileges::
2486fff6a4d3SAbhishek Patel                         postLogServiceSubOverComputerSystemLogServiceCollection)
24876ab9ad54SClaire Weinan         .methods(boost::beast::http::verb::post)(std::bind_front(
248822d268cbSEd Tanous             handleLogServicesDumpClearLogComputerSystemPost, std::ref(app)));
2489013487e5Sraviteja-b }
2490013487e5Sraviteja-b 
24917e860f15SJohn Edward Broadbent inline void requestRoutesCrashdumpService(App& app)
24921da66f75SEd Tanous {
24931da66f75SEd Tanous     /**
24941da66f75SEd Tanous      * Functions triggers appropriate requests on DBus
24951da66f75SEd Tanous      */
249622d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/Crashdump/")
249750d9f38aSMyung Bae         .privileges(redfish::privileges::getLogService)
2498bd79bce8SPatrick Williams         .methods(
2499bd79bce8SPatrick Williams             boost::beast::http::verb::
2500bd79bce8SPatrick Williams                 get)([&app](const crow::Request& req,
250122d268cbSEd Tanous                             const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
250222d268cbSEd Tanous                             const std::string& systemName) {
25033ba00073SCarson Labrado             if (!redfish::setUpRedfishRoute(app, req, asyncResp))
250445ca1b86SEd Tanous             {
250545ca1b86SEd Tanous                 return;
250645ca1b86SEd Tanous             }
250725b54dbaSEd Tanous             if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
25087f3e84a1SEd Tanous             {
25097f3e84a1SEd Tanous                 // Option currently returns no systems.  TBD
25107f3e84a1SEd Tanous                 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
25117f3e84a1SEd Tanous                                            systemName);
25127f3e84a1SEd Tanous                 return;
25137f3e84a1SEd Tanous             }
2514253f11b8SEd Tanous             if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
251522d268cbSEd Tanous             {
251622d268cbSEd Tanous                 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
251722d268cbSEd Tanous                                            systemName);
251822d268cbSEd Tanous                 return;
251922d268cbSEd Tanous             }
252022d268cbSEd Tanous 
25217e860f15SJohn Edward Broadbent             // Copy over the static data to include the entries added by
25227e860f15SJohn Edward Broadbent             // SubRoute
25230f74e643SEd Tanous             asyncResp->res.jsonValue["@odata.id"] =
2524253f11b8SEd Tanous                 std::format("/redfish/v1/Systems/{}/LogServices/Crashdump",
2525253f11b8SEd Tanous                             BMCWEB_REDFISH_SYSTEM_URI_NAME);
2526e1f26343SJason M. Bills             asyncResp->res.jsonValue["@odata.type"] =
25278e6c099aSJason M. Bills                 "#LogService.v1_2_0.LogService";
25284f50ae4bSGunnar Mills             asyncResp->res.jsonValue["Name"] = "Open BMC Oem Crashdump Service";
25294f50ae4bSGunnar Mills             asyncResp->res.jsonValue["Description"] = "Oem Crashdump Service";
253015b89725SV-Sanjana             asyncResp->res.jsonValue["Id"] = "Crashdump";
2531539d8c6bSEd Tanous             asyncResp->res.jsonValue["OverWritePolicy"] =
2532539d8c6bSEd Tanous                 log_service::OverWritePolicy::WrapsWhenFull;
2533e1f26343SJason M. Bills             asyncResp->res.jsonValue["MaxNumberOfRecords"] = 3;
25347c8c4058STejas Patil 
25357c8c4058STejas Patil             std::pair<std::string, std::string> redfishDateTimeOffset =
25362b82937eSEd Tanous                 redfish::time_utils::getDateTimeOffsetNow();
25377c8c4058STejas Patil             asyncResp->res.jsonValue["DateTime"] = redfishDateTimeOffset.first;
25387c8c4058STejas Patil             asyncResp->res.jsonValue["DateTimeLocalOffset"] =
25397c8c4058STejas Patil                 redfishDateTimeOffset.second;
25407c8c4058STejas Patil 
2541bd79bce8SPatrick Williams             asyncResp->res.jsonValue["Entries"]["@odata.id"] = std::format(
2542bd79bce8SPatrick Williams                 "/redfish/v1/Systems/{}/LogServices/Crashdump/Entries",
2543253f11b8SEd Tanous                 BMCWEB_REDFISH_SYSTEM_URI_NAME);
2544253f11b8SEd Tanous             asyncResp->res.jsonValue["Actions"]["#LogService.ClearLog"]
2545253f11b8SEd Tanous                                     ["target"] = std::format(
2546253f11b8SEd Tanous                 "/redfish/v1/Systems/{}/LogServices/Crashdump/Actions/LogService.ClearLog",
2547253f11b8SEd Tanous                 BMCWEB_REDFISH_SYSTEM_URI_NAME);
2548bd79bce8SPatrick Williams             asyncResp->res
2549bd79bce8SPatrick Williams                 .jsonValue["Actions"]["#LogService.CollectDiagnosticData"]
2550253f11b8SEd Tanous                           ["target"] = std::format(
2551253f11b8SEd Tanous                 "/redfish/v1/Systems/{}/LogServices/Crashdump/Actions/LogService.CollectDiagnosticData",
2552253f11b8SEd Tanous                 BMCWEB_REDFISH_SYSTEM_URI_NAME);
25537e860f15SJohn Edward Broadbent         });
25541da66f75SEd Tanous }
25551da66f75SEd Tanous 
25568e4736b3SEd Tanous inline void requestRoutesCrashdumpClear(App& app)
25575b61b5e8SJason M. Bills {
25580fda0f12SGeorge Liu     BMCWEB_ROUTE(
25590fda0f12SGeorge Liu         app,
256022d268cbSEd Tanous         "/redfish/v1/Systems/<str>/LogServices/Crashdump/Actions/LogService.ClearLog/")
256150d9f38aSMyung Bae         .privileges(redfish::privileges::
256250d9f38aSMyung Bae                         postLogServiceSubOverComputerSystemLogServiceCollection)
25637e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::post)(
256445ca1b86SEd Tanous             [&app](const crow::Request& req,
256522d268cbSEd Tanous                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
256622d268cbSEd Tanous                    const std::string& systemName) {
25673ba00073SCarson Labrado                 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
256845ca1b86SEd Tanous                 {
256945ca1b86SEd Tanous                     return;
257045ca1b86SEd Tanous                 }
257125b54dbaSEd Tanous                 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
25727f3e84a1SEd Tanous                 {
25737f3e84a1SEd Tanous                     // Option currently returns no systems.  TBD
25747f3e84a1SEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
25757f3e84a1SEd Tanous                                                systemName);
25767f3e84a1SEd Tanous                     return;
25777f3e84a1SEd Tanous                 }
2578253f11b8SEd Tanous                 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
257922d268cbSEd Tanous                 {
258022d268cbSEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
258122d268cbSEd Tanous                                                systemName);
258222d268cbSEd Tanous                     return;
258322d268cbSEd Tanous                 }
2584177612aaSEd Tanous                 dbus::utility::async_method_call(
2585177612aaSEd Tanous                     asyncResp,
25865e7e2dc5SEd Tanous                     [asyncResp](const boost::system::error_code& ec,
2587cb13a392SEd Tanous                                 const std::string&) {
25885b61b5e8SJason M. Bills                         if (ec)
25895b61b5e8SJason M. Bills                         {
25905b61b5e8SJason M. Bills                             messages::internalError(asyncResp->res);
25915b61b5e8SJason M. Bills                             return;
25925b61b5e8SJason M. Bills                         }
25935b61b5e8SJason M. Bills                         messages::success(asyncResp->res);
25945b61b5e8SJason M. Bills                     },
2595bd79bce8SPatrick Williams                     crashdumpObject, crashdumpPath, deleteAllInterface,
2596bd79bce8SPatrick Williams                     "DeleteAll");
25977e860f15SJohn Edward Broadbent             });
25985b61b5e8SJason M. Bills }
25995b61b5e8SJason M. Bills 
2600504af5a0SPatrick Williams inline void logCrashdumpEntry(
2601504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
26028d1b46d7Szhanghch05     const std::string& logID, nlohmann::json& logEntryJson)
2603e855dd28SJason M. Bills {
2604043a0536SJohnathan Mantey     auto getStoredLogCallback =
2605b9d36b47SEd Tanous         [asyncResp, logID,
26065e7e2dc5SEd Tanous          &logEntryJson](const boost::system::error_code& ec,
2607b9d36b47SEd Tanous                         const dbus::utility::DBusPropertiesMap& params) {
2608e855dd28SJason M. Bills             if (ec)
2609e855dd28SJason M. Bills             {
261062598e31SEd Tanous                 BMCWEB_LOG_DEBUG("failed to get log ec: {}", ec.message());
26111ddcf01aSJason M. Bills                 if (ec.value() ==
26121ddcf01aSJason M. Bills                     boost::system::linux_error::bad_request_descriptor)
26131ddcf01aSJason M. Bills                 {
2614bd79bce8SPatrick Williams                     messages::resourceNotFound(asyncResp->res, "LogEntry",
2615bd79bce8SPatrick Williams                                                logID);
26161ddcf01aSJason M. Bills                 }
26171ddcf01aSJason M. Bills                 else
26181ddcf01aSJason M. Bills                 {
2619e855dd28SJason M. Bills                     messages::internalError(asyncResp->res);
26201ddcf01aSJason M. Bills                 }
2621e855dd28SJason M. Bills                 return;
2622e855dd28SJason M. Bills             }
2623043a0536SJohnathan Mantey 
2624043a0536SJohnathan Mantey             std::string timestamp{};
2625043a0536SJohnathan Mantey             std::string filename{};
2626043a0536SJohnathan Mantey             std::string logfile{};
26272c70f800SEd Tanous             parseCrashdumpParameters(params, filename, timestamp, logfile);
2628043a0536SJohnathan Mantey 
2629043a0536SJohnathan Mantey             if (filename.empty() || timestamp.empty())
2630e855dd28SJason M. Bills             {
26319db4ba25SJiaqing Zhao                 messages::resourceNotFound(asyncResp->res, "LogEntry", logID);
2632e855dd28SJason M. Bills                 return;
2633e855dd28SJason M. Bills             }
2634e855dd28SJason M. Bills 
2635043a0536SJohnathan Mantey             std::string crashdumpURI =
2636bd79bce8SPatrick Williams                 std::format(
2637bd79bce8SPatrick Williams                     "/redfish/v1/Systems/{}/LogServices/Crashdump/Entries/",
2638253f11b8SEd Tanous                     BMCWEB_REDFISH_SYSTEM_URI_NAME) +
2639043a0536SJohnathan Mantey                 logID + "/" + filename;
264084afc48bSJason M. Bills             nlohmann::json::object_t logEntry;
26419c11a172SVijay Lobo             logEntry["@odata.type"] = "#LogEntry.v1_9_0.LogEntry";
2642ef4c65b7SEd Tanous             logEntry["@odata.id"] = boost::urls::format(
2643253f11b8SEd Tanous                 "/redfish/v1/Systems/{}/LogServices/Crashdump/Entries/{}",
2644253f11b8SEd Tanous                 BMCWEB_REDFISH_SYSTEM_URI_NAME, logID);
264584afc48bSJason M. Bills             logEntry["Name"] = "CPU Crashdump";
264684afc48bSJason M. Bills             logEntry["Id"] = logID;
2647539d8c6bSEd Tanous             logEntry["EntryType"] = log_entry::LogEntryType::Oem;
264884afc48bSJason M. Bills             logEntry["AdditionalDataURI"] = std::move(crashdumpURI);
264984afc48bSJason M. Bills             logEntry["DiagnosticDataType"] = "OEM";
265084afc48bSJason M. Bills             logEntry["OEMDiagnosticDataType"] = "PECICrashdump";
265184afc48bSJason M. Bills             logEntry["Created"] = std::move(timestamp);
26522b20ef6eSJason M. Bills 
26532b20ef6eSJason M. Bills             // If logEntryJson references an array of LogEntry resources
26542b20ef6eSJason M. Bills             // ('Members' list), then push this as a new entry, otherwise set it
26552b20ef6eSJason M. Bills             // directly
26562b20ef6eSJason M. Bills             if (logEntryJson.is_array())
26572b20ef6eSJason M. Bills             {
26582b20ef6eSJason M. Bills                 logEntryJson.push_back(logEntry);
26592b20ef6eSJason M. Bills                 asyncResp->res.jsonValue["Members@odata.count"] =
26602b20ef6eSJason M. Bills                     logEntryJson.size();
26612b20ef6eSJason M. Bills             }
26622b20ef6eSJason M. Bills             else
26632b20ef6eSJason M. Bills             {
2664d405bb51SJason M. Bills                 logEntryJson.update(logEntry);
26652b20ef6eSJason M. Bills             }
2666e855dd28SJason M. Bills         };
2667deae6a78SEd Tanous     dbus::utility::getAllProperties(
2668deae6a78SEd Tanous         crashdumpObject, crashdumpPath + std::string("/") + logID,
2669deae6a78SEd Tanous         crashdumpInterface, std::move(getStoredLogCallback));
2670e855dd28SJason M. Bills }
2671e855dd28SJason M. Bills 
26727e860f15SJohn Edward Broadbent inline void requestRoutesCrashdumpEntryCollection(App& app)
26731da66f75SEd Tanous {
26741da66f75SEd Tanous     /**
26751da66f75SEd Tanous      * Functions triggers appropriate requests on DBus
26761da66f75SEd Tanous      */
26777e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app,
267822d268cbSEd Tanous                  "/redfish/v1/Systems/<str>/LogServices/Crashdump/Entries/")
267950d9f38aSMyung Bae         .privileges(redfish::privileges::getLogEntryCollection)
2680bd79bce8SPatrick Williams         .methods(
2681bd79bce8SPatrick Williams             boost::beast::http::verb::
2682bd79bce8SPatrick Williams                 get)([&app](const crow::Request& req,
268322d268cbSEd Tanous                             const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
268422d268cbSEd Tanous                             const std::string& systemName) {
26853ba00073SCarson Labrado             if (!redfish::setUpRedfishRoute(app, req, asyncResp))
268645ca1b86SEd Tanous             {
268745ca1b86SEd Tanous                 return;
268845ca1b86SEd Tanous             }
268925b54dbaSEd Tanous             if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
26907f3e84a1SEd Tanous             {
26917f3e84a1SEd Tanous                 // Option currently returns no systems.  TBD
26927f3e84a1SEd Tanous                 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
26937f3e84a1SEd Tanous                                            systemName);
26947f3e84a1SEd Tanous                 return;
26957f3e84a1SEd Tanous             }
2696253f11b8SEd Tanous             if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
269722d268cbSEd Tanous             {
269822d268cbSEd Tanous                 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
269922d268cbSEd Tanous                                            systemName);
270022d268cbSEd Tanous                 return;
270122d268cbSEd Tanous             }
270222d268cbSEd Tanous 
27037a1dbc48SGeorge Liu             constexpr std::array<std::string_view, 1> interfaces = {
27047a1dbc48SGeorge Liu                 crashdumpInterface};
27057a1dbc48SGeorge Liu             dbus::utility::getSubTreePaths(
27067a1dbc48SGeorge Liu                 "/", 0, interfaces,
27077a1dbc48SGeorge Liu                 [asyncResp](const boost::system::error_code& ec,
27082b20ef6eSJason M. Bills                             const std::vector<std::string>& resp) {
27091da66f75SEd Tanous                     if (ec)
27101da66f75SEd Tanous                     {
27111da66f75SEd Tanous                         if (ec.value() !=
27121da66f75SEd Tanous                             boost::system::errc::no_such_file_or_directory)
27131da66f75SEd Tanous                         {
271462598e31SEd Tanous                             BMCWEB_LOG_DEBUG("failed to get entries ec: {}",
271562598e31SEd Tanous                                              ec.message());
2716f12894f8SJason M. Bills                             messages::internalError(asyncResp->res);
27171da66f75SEd Tanous                             return;
27181da66f75SEd Tanous                         }
27191da66f75SEd Tanous                     }
2720e1f26343SJason M. Bills                     asyncResp->res.jsonValue["@odata.type"] =
27211da66f75SEd Tanous                         "#LogEntryCollection.LogEntryCollection";
2722253f11b8SEd Tanous                     asyncResp->res.jsonValue["@odata.id"] = std::format(
2723253f11b8SEd Tanous                         "/redfish/v1/Systems/{}/LogServices/Crashdump/Entries",
2724253f11b8SEd Tanous                         BMCWEB_REDFISH_SYSTEM_URI_NAME);
2725bd79bce8SPatrick Williams                     asyncResp->res.jsonValue["Name"] =
2726bd79bce8SPatrick Williams                         "Open BMC Crashdump Entries";
2727e1f26343SJason M. Bills                     asyncResp->res.jsonValue["Description"] =
2728424c4176SJason M. Bills                         "Collection of Crashdump Entries";
2729bd79bce8SPatrick Williams                     asyncResp->res.jsonValue["Members"] =
2730bd79bce8SPatrick Williams                         nlohmann::json::array();
2731a2dd60a6SBrandon Kim                     asyncResp->res.jsonValue["Members@odata.count"] = 0;
27322b20ef6eSJason M. Bills 
27332b20ef6eSJason M. Bills                     for (const std::string& path : resp)
27341da66f75SEd Tanous                     {
27352b20ef6eSJason M. Bills                         const sdbusplus::message::object_path objPath(path);
2736e855dd28SJason M. Bills                         // Get the log ID
27372b20ef6eSJason M. Bills                         std::string logID = objPath.filename();
27382b20ef6eSJason M. Bills                         if (logID.empty())
27391da66f75SEd Tanous                         {
2740e855dd28SJason M. Bills                             continue;
27411da66f75SEd Tanous                         }
2742e855dd28SJason M. Bills                         // Add the log entry to the array
27432b20ef6eSJason M. Bills                         logCrashdumpEntry(asyncResp, logID,
27442b20ef6eSJason M. Bills                                           asyncResp->res.jsonValue["Members"]);
27451da66f75SEd Tanous                     }
27467a1dbc48SGeorge Liu                 });
27477e860f15SJohn Edward Broadbent         });
27481da66f75SEd Tanous }
27491da66f75SEd Tanous 
27507e860f15SJohn Edward Broadbent inline void requestRoutesCrashdumpEntry(App& app)
27511da66f75SEd Tanous {
27527e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(
275322d268cbSEd Tanous         app, "/redfish/v1/Systems/<str>/LogServices/Crashdump/Entries/<str>/")
275450d9f38aSMyung Bae         .privileges(redfish::privileges::getLogEntry)
27557e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
275645ca1b86SEd Tanous             [&app](const crow::Request& req,
27577e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
275822d268cbSEd Tanous                    const std::string& systemName, const std::string& param) {
27593ba00073SCarson Labrado                 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
276045ca1b86SEd Tanous                 {
276145ca1b86SEd Tanous                     return;
276245ca1b86SEd Tanous                 }
276325b54dbaSEd Tanous                 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
27647f3e84a1SEd Tanous                 {
27657f3e84a1SEd Tanous                     // Option currently returns no systems.  TBD
27667f3e84a1SEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
27677f3e84a1SEd Tanous                                                systemName);
27687f3e84a1SEd Tanous                     return;
27697f3e84a1SEd Tanous                 }
2770253f11b8SEd Tanous                 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
277122d268cbSEd Tanous                 {
277222d268cbSEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
277322d268cbSEd Tanous                                                systemName);
277422d268cbSEd Tanous                     return;
277522d268cbSEd Tanous                 }
27767e860f15SJohn Edward Broadbent                 const std::string& logID = param;
2777e855dd28SJason M. Bills                 logCrashdumpEntry(asyncResp, logID, asyncResp->res.jsonValue);
27787e860f15SJohn Edward Broadbent             });
2779e855dd28SJason M. Bills }
2780e855dd28SJason M. Bills 
27817e860f15SJohn Edward Broadbent inline void requestRoutesCrashdumpFile(App& app)
2782e855dd28SJason M. Bills {
27837e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(
27847e860f15SJohn Edward Broadbent         app,
278522d268cbSEd Tanous         "/redfish/v1/Systems/<str>/LogServices/Crashdump/Entries/<str>/<str>/")
2786ed398213SEd Tanous         .privileges(redfish::privileges::getLogEntry)
27877e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
2788a4ce114aSNan Zhou             [](const crow::Request& req,
27897e860f15SJohn Edward Broadbent                const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
279022d268cbSEd Tanous                const std::string& systemName, const std::string& logID,
279122d268cbSEd Tanous                const std::string& fileName) {
2792bd79bce8SPatrick Williams                 // Do not call getRedfishRoute here since the crashdump file is
2793bd79bce8SPatrick Williams                 // not a Redfish resource.
279422d268cbSEd Tanous 
279525b54dbaSEd Tanous                 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
27967f3e84a1SEd Tanous                 {
27977f3e84a1SEd Tanous                     // Option currently returns no systems.  TBD
27987f3e84a1SEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
27997f3e84a1SEd Tanous                                                systemName);
28007f3e84a1SEd Tanous                     return;
28017f3e84a1SEd Tanous                 }
2802253f11b8SEd Tanous                 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
280322d268cbSEd Tanous                 {
280422d268cbSEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
280522d268cbSEd Tanous                                                systemName);
280622d268cbSEd Tanous                     return;
280722d268cbSEd Tanous                 }
280822d268cbSEd Tanous 
2809043a0536SJohnathan Mantey                 auto getStoredLogCallback =
2810bd79bce8SPatrick Williams                     [asyncResp, logID, fileName,
2811bd79bce8SPatrick Williams                      url(boost::urls::url(req.url()))](
28125e7e2dc5SEd Tanous                         const boost::system::error_code& ec,
2813bd79bce8SPatrick Williams                         const std::vector<std::pair<
2814bd79bce8SPatrick Williams                             std::string, dbus::utility::DbusVariantType>>&
28157e860f15SJohn Edward Broadbent                             resp) {
28161da66f75SEd Tanous                         if (ec)
28171da66f75SEd Tanous                         {
2818bd79bce8SPatrick Williams                             BMCWEB_LOG_DEBUG("failed to get log ec: {}",
2819bd79bce8SPatrick Williams                                              ec.message());
2820f12894f8SJason M. Bills                             messages::internalError(asyncResp->res);
28211da66f75SEd Tanous                             return;
28221da66f75SEd Tanous                         }
2823e855dd28SJason M. Bills 
2824043a0536SJohnathan Mantey                         std::string dbusFilename{};
2825043a0536SJohnathan Mantey                         std::string dbusTimestamp{};
2826043a0536SJohnathan Mantey                         std::string dbusFilepath{};
2827043a0536SJohnathan Mantey 
2828bd79bce8SPatrick Williams                         parseCrashdumpParameters(resp, dbusFilename,
2829bd79bce8SPatrick Williams                                                  dbusTimestamp, dbusFilepath);
2830043a0536SJohnathan Mantey 
2831043a0536SJohnathan Mantey                         if (dbusFilename.empty() || dbusTimestamp.empty() ||
2832043a0536SJohnathan Mantey                             dbusFilepath.empty())
28331da66f75SEd Tanous                         {
2834bd79bce8SPatrick Williams                             messages::resourceNotFound(asyncResp->res,
2835bd79bce8SPatrick Williams                                                        "LogEntry", logID);
28361da66f75SEd Tanous                             return;
28371da66f75SEd Tanous                         }
2838e855dd28SJason M. Bills 
2839043a0536SJohnathan Mantey                         // Verify the file name parameter is correct
2840043a0536SJohnathan Mantey                         if (fileName != dbusFilename)
2841043a0536SJohnathan Mantey                         {
2842bd79bce8SPatrick Williams                             messages::resourceNotFound(asyncResp->res,
2843bd79bce8SPatrick Williams                                                        "LogEntry", logID);
2844043a0536SJohnathan Mantey                             return;
2845043a0536SJohnathan Mantey                         }
2846043a0536SJohnathan Mantey 
2847d51c61b4SMyung Bae                         if (asyncResp->res.openFile(dbusFilepath) !=
2848d51c61b4SMyung Bae                             crow::OpenCode::Success)
2849043a0536SJohnathan Mantey                         {
2850bd79bce8SPatrick Williams                             messages::resourceNotFound(asyncResp->res,
2851bd79bce8SPatrick Williams                                                        "LogEntry", logID);
2852043a0536SJohnathan Mantey                             return;
2853043a0536SJohnathan Mantey                         }
2854043a0536SJohnathan Mantey 
28557e860f15SJohn Edward Broadbent                         // Configure this to be a file download when accessed
28567e860f15SJohn Edward Broadbent                         // from a browser
2857d9f6c621SEd Tanous                         asyncResp->res.addHeader(
2858bd79bce8SPatrick Williams                             boost::beast::http::field::content_disposition,
2859bd79bce8SPatrick Williams                             "attachment");
28601da66f75SEd Tanous                     };
2861deae6a78SEd Tanous                 dbus::utility::getAllProperties(
2862d1bde9e5SKrzysztof Grobelny                     *crow::connections::systemBus, crashdumpObject,
2863bd79bce8SPatrick Williams                     crashdumpPath + std::string("/") + logID,
2864bd79bce8SPatrick Williams                     crashdumpInterface, std::move(getStoredLogCallback));
28657e860f15SJohn Edward Broadbent             });
28661da66f75SEd Tanous }
28671da66f75SEd Tanous 
2868c5a4c82aSJason M. Bills enum class OEMDiagnosticType
2869c5a4c82aSJason M. Bills {
2870c5a4c82aSJason M. Bills     onDemand,
2871c5a4c82aSJason M. Bills     telemetry,
2872c5a4c82aSJason M. Bills     invalid,
2873c5a4c82aSJason M. Bills };
2874c5a4c82aSJason M. Bills 
287526ccae32SEd Tanous inline OEMDiagnosticType getOEMDiagnosticType(std::string_view oemDiagStr)
2876c5a4c82aSJason M. Bills {
2877c5a4c82aSJason M. Bills     if (oemDiagStr == "OnDemand")
2878c5a4c82aSJason M. Bills     {
2879c5a4c82aSJason M. Bills         return OEMDiagnosticType::onDemand;
2880c5a4c82aSJason M. Bills     }
2881c5a4c82aSJason M. Bills     if (oemDiagStr == "Telemetry")
2882c5a4c82aSJason M. Bills     {
2883c5a4c82aSJason M. Bills         return OEMDiagnosticType::telemetry;
2884c5a4c82aSJason M. Bills     }
2885c5a4c82aSJason M. Bills 
2886c5a4c82aSJason M. Bills     return OEMDiagnosticType::invalid;
2887c5a4c82aSJason M. Bills }
2888c5a4c82aSJason M. Bills 
28897e860f15SJohn Edward Broadbent inline void requestRoutesCrashdumpCollect(App& app)
28901da66f75SEd Tanous {
28910fda0f12SGeorge Liu     BMCWEB_ROUTE(
28920fda0f12SGeorge Liu         app,
289322d268cbSEd Tanous         "/redfish/v1/Systems/<str>/LogServices/Crashdump/Actions/LogService.CollectDiagnosticData/")
289450d9f38aSMyung Bae         .privileges(redfish::privileges::
289550d9f38aSMyung Bae                         postLogServiceSubOverComputerSystemLogServiceCollection)
2896002d39b4SEd Tanous         .methods(boost::beast::http::verb::post)(
2897002d39b4SEd Tanous             [&app](const crow::Request& req,
289822d268cbSEd Tanous                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
289922d268cbSEd Tanous                    const std::string& systemName) {
29003ba00073SCarson Labrado                 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
290145ca1b86SEd Tanous                 {
290245ca1b86SEd Tanous                     return;
290345ca1b86SEd Tanous                 }
290422d268cbSEd Tanous 
290525b54dbaSEd Tanous                 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
29067f3e84a1SEd Tanous                 {
29077f3e84a1SEd Tanous                     // Option currently returns no systems.  TBD
29087f3e84a1SEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
29097f3e84a1SEd Tanous                                                systemName);
29107f3e84a1SEd Tanous                     return;
29117f3e84a1SEd Tanous                 }
2912253f11b8SEd Tanous                 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
291322d268cbSEd Tanous                 {
291422d268cbSEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
291522d268cbSEd Tanous                                                systemName);
291622d268cbSEd Tanous                     return;
291722d268cbSEd Tanous                 }
291822d268cbSEd Tanous 
29198e6c099aSJason M. Bills                 std::string diagnosticDataType;
29208e6c099aSJason M. Bills                 std::string oemDiagnosticDataType;
2921afc474aeSMyung Bae                 if (!redfish::json_util::readJsonAction(               //
2922afc474aeSMyung Bae                         req, asyncResp->res,                           //
2923afc474aeSMyung Bae                         "DiagnosticDataType", diagnosticDataType,      //
2924afc474aeSMyung Bae                         "OEMDiagnosticDataType", oemDiagnosticDataType //
2925afc474aeSMyung Bae                         ))
29268e6c099aSJason M. Bills                 {
29278e6c099aSJason M. Bills                     return;
29288e6c099aSJason M. Bills                 }
29298e6c099aSJason M. Bills 
29308e6c099aSJason M. Bills                 if (diagnosticDataType != "OEM")
29318e6c099aSJason M. Bills                 {
293262598e31SEd Tanous                     BMCWEB_LOG_ERROR(
293362598e31SEd Tanous                         "Only OEM DiagnosticDataType supported for Crashdump");
29348e6c099aSJason M. Bills                     messages::actionParameterValueFormatError(
2935bd79bce8SPatrick Williams                         asyncResp->res, diagnosticDataType,
2936bd79bce8SPatrick Williams                         "DiagnosticDataType", "CollectDiagnosticData");
29378e6c099aSJason M. Bills                     return;
29388e6c099aSJason M. Bills                 }
29398e6c099aSJason M. Bills 
2940c5a4c82aSJason M. Bills                 OEMDiagnosticType oemDiagType =
2941c5a4c82aSJason M. Bills                     getOEMDiagnosticType(oemDiagnosticDataType);
2942c5a4c82aSJason M. Bills 
2943c5a4c82aSJason M. Bills                 std::string iface;
2944c5a4c82aSJason M. Bills                 std::string method;
2945c5a4c82aSJason M. Bills                 std::string taskMatchStr;
2946c5a4c82aSJason M. Bills                 if (oemDiagType == OEMDiagnosticType::onDemand)
2947c5a4c82aSJason M. Bills                 {
2948c5a4c82aSJason M. Bills                     iface = crashdumpOnDemandInterface;
2949c5a4c82aSJason M. Bills                     method = "GenerateOnDemandLog";
2950bd79bce8SPatrick Williams                     taskMatchStr =
2951bd79bce8SPatrick Williams                         "type='signal',"
2952c5a4c82aSJason M. Bills                         "interface='org.freedesktop.DBus.Properties',"
2953c5a4c82aSJason M. Bills                         "member='PropertiesChanged',"
2954c5a4c82aSJason M. Bills                         "arg0namespace='com.intel.crashdump'";
2955c5a4c82aSJason M. Bills                 }
2956c5a4c82aSJason M. Bills                 else if (oemDiagType == OEMDiagnosticType::telemetry)
2957c5a4c82aSJason M. Bills                 {
2958c5a4c82aSJason M. Bills                     iface = crashdumpTelemetryInterface;
2959c5a4c82aSJason M. Bills                     method = "GenerateTelemetryLog";
2960bd79bce8SPatrick Williams                     taskMatchStr =
2961bd79bce8SPatrick Williams                         "type='signal',"
2962c5a4c82aSJason M. Bills                         "interface='org.freedesktop.DBus.Properties',"
2963c5a4c82aSJason M. Bills                         "member='PropertiesChanged',"
2964c5a4c82aSJason M. Bills                         "arg0namespace='com.intel.crashdump'";
2965c5a4c82aSJason M. Bills                 }
2966c5a4c82aSJason M. Bills                 else
2967c5a4c82aSJason M. Bills                 {
296862598e31SEd Tanous                     BMCWEB_LOG_ERROR("Unsupported OEMDiagnosticDataType: {}",
296962598e31SEd Tanous                                      oemDiagnosticDataType);
2970c5a4c82aSJason M. Bills                     messages::actionParameterValueFormatError(
2971bd79bce8SPatrick Williams                         asyncResp->res, oemDiagnosticDataType,
2972bd79bce8SPatrick Williams                         "OEMDiagnosticDataType", "CollectDiagnosticData");
2973c5a4c82aSJason M. Bills                     return;
2974c5a4c82aSJason M. Bills                 }
2975c5a4c82aSJason M. Bills 
2976c5a4c82aSJason M. Bills                 auto collectCrashdumpCallback =
2977c5a4c82aSJason M. Bills                     [asyncResp, payload(task::Payload(req)),
29785e7e2dc5SEd Tanous                      taskMatchStr](const boost::system::error_code& ec,
297998be3e39SEd Tanous                                    const std::string&) mutable {
29801da66f75SEd Tanous                         if (ec)
29811da66f75SEd Tanous                         {
2982bd79bce8SPatrick Williams                             if (ec.value() ==
2983bd79bce8SPatrick Williams                                 boost::system::errc::operation_not_supported)
29841da66f75SEd Tanous                             {
2985f12894f8SJason M. Bills                                 messages::resourceInStandby(asyncResp->res);
29861da66f75SEd Tanous                             }
2987bd79bce8SPatrick Williams                             else if (ec.value() == boost::system::errc::
2988bd79bce8SPatrick Williams                                                        device_or_resource_busy)
29894363d3b2SJason M. Bills                             {
2990bd79bce8SPatrick Williams                                 messages::serviceTemporarilyUnavailable(
2991bd79bce8SPatrick Williams                                     asyncResp->res, "60");
29924363d3b2SJason M. Bills                             }
29931da66f75SEd Tanous                             else
29941da66f75SEd Tanous                             {
2995f12894f8SJason M. Bills                                 messages::internalError(asyncResp->res);
29961da66f75SEd Tanous                             }
29971da66f75SEd Tanous                             return;
29981da66f75SEd Tanous                         }
2999bd79bce8SPatrick Williams                         std::shared_ptr<task::TaskData> task =
3000bd79bce8SPatrick Williams                             task::TaskData::createTask(
3001bd79bce8SPatrick Williams                                 [](const boost::system::error_code& ec2,
3002bd79bce8SPatrick Williams                                    sdbusplus::message_t&,
3003bd79bce8SPatrick Williams                                    const std::shared_ptr<task::TaskData>&
3004bd79bce8SPatrick Williams                                        taskData) {
30058b24275dSEd Tanous                                     if (!ec2)
300666afe4faSJames Feist                                     {
3007bd79bce8SPatrick Williams                                         taskData->messages.emplace_back(
3008bd79bce8SPatrick Williams                                             messages::taskCompletedOK(
3009bd79bce8SPatrick Williams                                                 std::to_string(
3010bd79bce8SPatrick Williams                                                     taskData->index)));
3011831d6b09SJames Feist                                         taskData->state = "Completed";
301266afe4faSJames Feist                                     }
301332898ceaSJames Feist                                     return task::completed;
301466afe4faSJames Feist                                 },
3015c5a4c82aSJason M. Bills                                 taskMatchStr);
3016c5a4c82aSJason M. Bills 
301746229577SJames Feist                         task->startTimer(std::chrono::minutes(5));
301898be3e39SEd Tanous                         task->payload.emplace(std::move(payload));
301929e2bdd7SChinmay Shripad Hegde                         task->populateResp(asyncResp->res);
30201da66f75SEd Tanous                     };
30218e6c099aSJason M. Bills 
3022177612aaSEd Tanous                 dbus::utility::async_method_call(
3023177612aaSEd Tanous                     asyncResp, std::move(collectCrashdumpCallback),
3024177612aaSEd Tanous                     crashdumpObject, crashdumpPath, iface, method);
30257e860f15SJohn Edward Broadbent             });
30266eda7685SKenny L. Ku }
30276eda7685SKenny L. Ku 
3028599b9af3SAlexander Hansen inline void dBusLogServiceActionsClear(
3029599b9af3SAlexander Hansen     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
3030599b9af3SAlexander Hansen {
3031599b9af3SAlexander Hansen     BMCWEB_LOG_DEBUG("Do delete all entries.");
3032599b9af3SAlexander Hansen 
3033599b9af3SAlexander Hansen     // Process response from Logging service.
3034599b9af3SAlexander Hansen     auto respHandler = [asyncResp](const boost::system::error_code& ec) {
3035599b9af3SAlexander Hansen         BMCWEB_LOG_DEBUG("doClearLog resp_handler callback: Done");
3036599b9af3SAlexander Hansen         if (ec)
3037599b9af3SAlexander Hansen         {
3038599b9af3SAlexander Hansen             // TODO Handle for specific error code
3039599b9af3SAlexander Hansen             BMCWEB_LOG_ERROR("doClearLog resp_handler got error {}", ec);
3040599b9af3SAlexander Hansen             asyncResp->res.result(
3041599b9af3SAlexander Hansen                 boost::beast::http::status::internal_server_error);
3042599b9af3SAlexander Hansen             return;
3043599b9af3SAlexander Hansen         }
3044599b9af3SAlexander Hansen 
3045e2460466SAmy Chang         messages::success(asyncResp->res);
3046599b9af3SAlexander Hansen     };
3047599b9af3SAlexander Hansen 
3048599b9af3SAlexander Hansen     // Make call to Logging service to request Clear Log
3049177612aaSEd Tanous     dbus::utility::async_method_call(
3050177612aaSEd Tanous         asyncResp, respHandler, "xyz.openbmc_project.Logging",
3051599b9af3SAlexander Hansen         "/xyz/openbmc_project/logging",
3052599b9af3SAlexander Hansen         "xyz.openbmc_project.Collection.DeleteAll", "DeleteAll");
3053599b9af3SAlexander Hansen }
3054599b9af3SAlexander Hansen 
3055cb92c03bSAndrew Geissler /**
3056cb92c03bSAndrew Geissler  * DBusLogServiceActionsClear class supports POST method for ClearLog action.
3057cb92c03bSAndrew Geissler  */
30587e860f15SJohn Edward Broadbent inline void requestRoutesDBusLogServiceActionsClear(App& app)
3059cb92c03bSAndrew Geissler {
3060cb92c03bSAndrew Geissler     /**
3061cb92c03bSAndrew Geissler      * Function handles POST method request.
3062cb92c03bSAndrew Geissler      * The Clear Log actions does not require any parameter.The action deletes
3063cb92c03bSAndrew Geissler      * all entries found in the Entries collection for this Log Service.
3064cb92c03bSAndrew Geissler      */
30657e860f15SJohn Edward Broadbent 
30660fda0f12SGeorge Liu     BMCWEB_ROUTE(
30670fda0f12SGeorge Liu         app,
306822d268cbSEd Tanous         "/redfish/v1/Systems/<str>/LogServices/EventLog/Actions/LogService.ClearLog/")
3069fff6a4d3SAbhishek Patel         .privileges(redfish::privileges::
3070fff6a4d3SAbhishek Patel                         postLogServiceSubOverComputerSystemLogServiceCollection)
30717e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::post)(
307245ca1b86SEd Tanous             [&app](const crow::Request& req,
307322d268cbSEd Tanous                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
307422d268cbSEd Tanous                    const std::string& systemName) {
30753ba00073SCarson Labrado                 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
307645ca1b86SEd Tanous                 {
307745ca1b86SEd Tanous                     return;
307845ca1b86SEd Tanous                 }
307925b54dbaSEd Tanous                 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
30807f3e84a1SEd Tanous                 {
30817f3e84a1SEd Tanous                     // Option currently returns no systems.  TBD
30827f3e84a1SEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
30837f3e84a1SEd Tanous                                                systemName);
30847f3e84a1SEd Tanous                     return;
30857f3e84a1SEd Tanous                 }
3086253f11b8SEd Tanous                 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
308722d268cbSEd Tanous                 {
308822d268cbSEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
308922d268cbSEd Tanous                                                systemName);
309022d268cbSEd Tanous                     return;
309122d268cbSEd Tanous                 }
3092599b9af3SAlexander Hansen                 dBusLogServiceActionsClear(asyncResp);
30937e860f15SJohn Edward Broadbent             });
3094cb92c03bSAndrew Geissler }
3095a3316fc6SZhikuiRen 
30961da66f75SEd Tanous } // namespace redfish
3097