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