| Ed Tanous | 1da66f7 | 2018-07-27 16:13:37 -0700 | [diff] [blame] | 1 | /* | 
 | 2 | // Copyright (c) 2018 Intel Corporation | 
 | 3 | // | 
 | 4 | // Licensed under the Apache License, Version 2.0 (the "License"); | 
 | 5 | // you may not use this file except in compliance with the License. | 
 | 6 | // You may obtain a copy of the License at | 
 | 7 | // | 
 | 8 | //      http://www.apache.org/licenses/LICENSE-2.0 | 
 | 9 | // | 
 | 10 | // Unless required by applicable law or agreed to in writing, software | 
 | 11 | // distributed under the License is distributed on an "AS IS" BASIS, | 
 | 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
 | 13 | // See the License for the specific language governing permissions and | 
 | 14 | // limitations under the License. | 
 | 15 | */ | 
 | 16 | #pragma once | 
 | 17 |  | 
| Ed Tanous | 3ccb3ad | 2023-01-13 17:40:03 -0800 | [diff] [blame] | 18 | #include "app.hpp" | 
| George Liu | 7a1dbc4 | 2022-12-07 16:03:22 +0800 | [diff] [blame] | 19 | #include "dbus_utility.hpp" | 
| Ed Tanous | 3ccb3ad | 2023-01-13 17:40:03 -0800 | [diff] [blame] | 20 | #include "error_messages.hpp" | 
| Asmitha Karunanithi | 68dd075 | 2022-11-15 11:33:46 -0600 | [diff] [blame] | 21 | #include "generated/enums/log_entry.hpp" | 
| Spencer Ku | b7028eb | 2021-10-26 15:27:35 +0800 | [diff] [blame] | 22 | #include "gzfile.hpp" | 
| George Liu | 647b3cd | 2021-07-05 12:43:56 +0800 | [diff] [blame] | 23 | #include "http_utility.hpp" | 
| Spencer Ku | b7028eb | 2021-10-26 15:27:35 +0800 | [diff] [blame] | 24 | #include "human_sort.hpp" | 
| Ed Tanous | 3ccb3ad | 2023-01-13 17:40:03 -0800 | [diff] [blame] | 25 | #include "query.hpp" | 
| Jason M. Bills | 4851d45 | 2019-03-28 11:27:48 -0700 | [diff] [blame] | 26 | #include "registries.hpp" | 
 | 27 | #include "registries/base_message_registry.hpp" | 
 | 28 | #include "registries/openbmc_message_registry.hpp" | 
| Ed Tanous | 3ccb3ad | 2023-01-13 17:40:03 -0800 | [diff] [blame] | 29 | #include "registries/privilege_registry.hpp" | 
| James Feist | 4622957 | 2020-02-19 15:11:58 -0800 | [diff] [blame] | 30 | #include "task.hpp" | 
| Ed Tanous | 3ccb3ad | 2023-01-13 17:40:03 -0800 | [diff] [blame] | 31 | #include "utils/dbus_utils.hpp" | 
 | 32 | #include "utils/time_utils.hpp" | 
| Ed Tanous | 1da66f7 | 2018-07-27 16:13:37 -0700 | [diff] [blame] | 33 |  | 
| Jason M. Bills | e1f2634 | 2018-07-18 12:12:00 -0700 | [diff] [blame] | 34 | #include <systemd/sd-journal.h> | 
| Asmitha Karunanithi | 8e31778 | 2020-12-10 03:35:05 -0600 | [diff] [blame] | 35 | #include <tinyxml2.h> | 
| Adriana Kobylak | 400fd1f | 2021-01-29 09:01:30 -0600 | [diff] [blame] | 36 | #include <unistd.h> | 
| Jason M. Bills | e1f2634 | 2018-07-18 12:12:00 -0700 | [diff] [blame] | 37 |  | 
| Ed Tanous | 9896eae | 2022-07-23 15:07:33 -0700 | [diff] [blame] | 38 | #include <boost/algorithm/string/case_conv.hpp> | 
| Ed Tanous | 11ba397 | 2022-07-11 09:50:41 -0700 | [diff] [blame] | 39 | #include <boost/algorithm/string/classification.hpp> | 
| Adriana Kobylak | 400fd1f | 2021-01-29 09:01:30 -0600 | [diff] [blame] | 40 | #include <boost/algorithm/string/replace.hpp> | 
| Jason M. Bills | 4851d45 | 2019-03-28 11:27:48 -0700 | [diff] [blame] | 41 | #include <boost/algorithm/string/split.hpp> | 
| Ed Tanous | 07c8c20 | 2022-07-11 10:08:08 -0700 | [diff] [blame] | 42 | #include <boost/beast/http/verb.hpp> | 
| Ed Tanous | 1da66f7 | 2018-07-27 16:13:37 -0700 | [diff] [blame] | 43 | #include <boost/container/flat_map.hpp> | 
| Jason M. Bills | 1ddcf01 | 2019-11-26 14:59:21 -0800 | [diff] [blame] | 44 | #include <boost/system/linux_error.hpp> | 
| Ed Tanous | ef4c65b | 2023-04-24 15:28:50 -0700 | [diff] [blame] | 45 | #include <boost/url/format.hpp> | 
| Krzysztof Grobelny | d1bde9e | 2022-09-07 10:40:51 +0200 | [diff] [blame] | 46 | #include <sdbusplus/asio/property.hpp> | 
 | 47 | #include <sdbusplus/unpack_properties.hpp> | 
| Gunnar Mills | 1214b7e | 2020-06-04 10:11:30 -0500 | [diff] [blame] | 48 |  | 
| George Liu | 7a1dbc4 | 2022-12-07 16:03:22 +0800 | [diff] [blame] | 49 | #include <array> | 
| George Liu | 647b3cd | 2021-07-05 12:43:56 +0800 | [diff] [blame] | 50 | #include <charconv> | 
| James Feist | 4418c7f | 2019-04-15 11:09:15 -0700 | [diff] [blame] | 51 | #include <filesystem> | 
| Xiaochao Ma | 75710de | 2021-01-21 17:56:02 +0800 | [diff] [blame] | 52 | #include <optional> | 
| Ed Tanous | 3544d2a | 2023-08-06 18:12:20 -0700 | [diff] [blame] | 53 | #include <ranges> | 
| Ed Tanous | 26702d0 | 2021-11-03 15:02:33 -0700 | [diff] [blame] | 54 | #include <span> | 
| Jason M. Bills | cd225da | 2019-05-08 15:31:57 -0700 | [diff] [blame] | 55 | #include <string_view> | 
| Ed Tanous | abf2add | 2019-01-22 16:40:12 -0800 | [diff] [blame] | 56 | #include <variant> | 
| Ed Tanous | 1da66f7 | 2018-07-27 16:13:37 -0700 | [diff] [blame] | 57 |  | 
 | 58 | namespace redfish | 
 | 59 | { | 
 | 60 |  | 
| Patrick Williams | 89492a1 | 2023-05-10 07:51:34 -0500 | [diff] [blame] | 61 | constexpr const char* crashdumpObject = "com.intel.crashdump"; | 
 | 62 | constexpr const char* crashdumpPath = "/com/intel/crashdump"; | 
 | 63 | constexpr const char* crashdumpInterface = "com.intel.crashdump"; | 
 | 64 | constexpr const char* deleteAllInterface = | 
| Jason M. Bills | 5b61b5e | 2019-10-16 10:59:02 -0700 | [diff] [blame] | 65 |     "xyz.openbmc_project.Collection.DeleteAll"; | 
| Patrick Williams | 89492a1 | 2023-05-10 07:51:34 -0500 | [diff] [blame] | 66 | constexpr const char* crashdumpOnDemandInterface = | 
| Jason M. Bills | 424c417 | 2019-03-21 13:50:33 -0700 | [diff] [blame] | 67 |     "com.intel.crashdump.OnDemand"; | 
| Patrick Williams | 89492a1 | 2023-05-10 07:51:34 -0500 | [diff] [blame] | 68 | constexpr const char* crashdumpTelemetryInterface = | 
| Kenny L. Ku | 6eda768 | 2020-06-19 09:48:36 -0700 | [diff] [blame] | 69 |     "com.intel.crashdump.Telemetry"; | 
| Ed Tanous | 1da66f7 | 2018-07-27 16:13:37 -0700 | [diff] [blame] | 70 |  | 
| Asmitha Karunanithi | 8e31778 | 2020-12-10 03:35:05 -0600 | [diff] [blame] | 71 | enum class DumpCreationProgress | 
 | 72 | { | 
 | 73 |     DUMP_CREATE_SUCCESS, | 
 | 74 |     DUMP_CREATE_FAILED, | 
 | 75 |     DUMP_CREATE_INPROGRESS | 
 | 76 | }; | 
 | 77 |  | 
| James Feist | f615040 | 2019-01-08 10:36:20 -0800 | [diff] [blame] | 78 | namespace fs = std::filesystem; | 
| Ed Tanous | 1da66f7 | 2018-07-27 16:13:37 -0700 | [diff] [blame] | 79 |  | 
| Gunnar Mills | 1214b7e | 2020-06-04 10:11:30 -0500 | [diff] [blame] | 80 | inline std::string translateSeverityDbusToRedfish(const std::string& s) | 
| Andrew Geissler | cb92c03 | 2018-08-17 07:56:14 -0700 | [diff] [blame] | 81 | { | 
| Ed Tanous | d4d2579 | 2020-09-29 15:15:03 -0700 | [diff] [blame] | 82 |     if ((s == "xyz.openbmc_project.Logging.Entry.Level.Alert") || | 
 | 83 |         (s == "xyz.openbmc_project.Logging.Entry.Level.Critical") || | 
 | 84 |         (s == "xyz.openbmc_project.Logging.Entry.Level.Emergency") || | 
 | 85 |         (s == "xyz.openbmc_project.Logging.Entry.Level.Error")) | 
| Andrew Geissler | cb92c03 | 2018-08-17 07:56:14 -0700 | [diff] [blame] | 86 |     { | 
 | 87 |         return "Critical"; | 
 | 88 |     } | 
| Ed Tanous | 3174e4d | 2020-10-07 11:41:22 -0700 | [diff] [blame] | 89 |     if ((s == "xyz.openbmc_project.Logging.Entry.Level.Debug") || | 
 | 90 |         (s == "xyz.openbmc_project.Logging.Entry.Level.Informational") || | 
 | 91 |         (s == "xyz.openbmc_project.Logging.Entry.Level.Notice")) | 
| Andrew Geissler | cb92c03 | 2018-08-17 07:56:14 -0700 | [diff] [blame] | 92 |     { | 
 | 93 |         return "OK"; | 
 | 94 |     } | 
| Ed Tanous | 3174e4d | 2020-10-07 11:41:22 -0700 | [diff] [blame] | 95 |     if (s == "xyz.openbmc_project.Logging.Entry.Level.Warning") | 
| Andrew Geissler | cb92c03 | 2018-08-17 07:56:14 -0700 | [diff] [blame] | 96 |     { | 
 | 97 |         return "Warning"; | 
 | 98 |     } | 
 | 99 |     return ""; | 
 | 100 | } | 
 | 101 |  | 
| Abhishek Patel | 9017faf | 2021-09-14 22:48:55 -0500 | [diff] [blame] | 102 | inline std::optional<bool> getProviderNotifyAction(const std::string& notify) | 
 | 103 | { | 
 | 104 |     std::optional<bool> notifyAction; | 
 | 105 |     if (notify == "xyz.openbmc_project.Logging.Entry.Notify.Notify") | 
 | 106 |     { | 
 | 107 |         notifyAction = true; | 
 | 108 |     } | 
 | 109 |     else if (notify == "xyz.openbmc_project.Logging.Entry.Notify.Inhibit") | 
 | 110 |     { | 
 | 111 |         notifyAction = false; | 
 | 112 |     } | 
 | 113 |  | 
 | 114 |     return notifyAction; | 
 | 115 | } | 
 | 116 |  | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 117 | inline static int getJournalMetadata(sd_journal* journal, | 
| Ed Tanous | 26ccae3 | 2023-02-16 10:28:44 -0800 | [diff] [blame] | 118 |                                      std::string_view field, | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 119 |                                      std::string_view& contents) | 
| Jason M. Bills | 16428a1 | 2018-11-02 12:42:29 -0700 | [diff] [blame] | 120 | { | 
| Gunnar Mills | 1214b7e | 2020-06-04 10:11:30 -0500 | [diff] [blame] | 121 |     const char* data = nullptr; | 
| Jason M. Bills | 16428a1 | 2018-11-02 12:42:29 -0700 | [diff] [blame] | 122 |     size_t length = 0; | 
 | 123 |     int ret = 0; | 
 | 124 |     // Get the metadata from the requested field of the journal entry | 
| Ed Tanous | 46ff87b | 2022-01-07 09:25:51 -0800 | [diff] [blame] | 125 |     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) | 
 | 126 |     const void** dataVoid = reinterpret_cast<const void**>(&data); | 
 | 127 |  | 
 | 128 |     ret = sd_journal_get_data(journal, field.data(), dataVoid, &length); | 
| Jason M. Bills | 16428a1 | 2018-11-02 12:42:29 -0700 | [diff] [blame] | 129 |     if (ret < 0) | 
 | 130 |     { | 
 | 131 |         return ret; | 
 | 132 |     } | 
| Ed Tanous | 39e7750 | 2019-03-04 17:35:53 -0800 | [diff] [blame] | 133 |     contents = std::string_view(data, length); | 
| Jason M. Bills | 16428a1 | 2018-11-02 12:42:29 -0700 | [diff] [blame] | 134 |     // Only use the content after the "=" character. | 
| Ed Tanous | 81ce609 | 2020-12-17 16:54:55 +0000 | [diff] [blame] | 135 |     contents.remove_prefix(std::min(contents.find('=') + 1, contents.size())); | 
| Jason M. Bills | 16428a1 | 2018-11-02 12:42:29 -0700 | [diff] [blame] | 136 |     return ret; | 
 | 137 | } | 
 | 138 |  | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 139 | inline static int getJournalMetadata(sd_journal* journal, | 
| Ed Tanous | 26ccae3 | 2023-02-16 10:28:44 -0800 | [diff] [blame] | 140 |                                      std::string_view field, const int& base, | 
 | 141 |                                      long int& contents) | 
| Jason M. Bills | 16428a1 | 2018-11-02 12:42:29 -0700 | [diff] [blame] | 142 | { | 
 | 143 |     int ret = 0; | 
| Ed Tanous | 39e7750 | 2019-03-04 17:35:53 -0800 | [diff] [blame] | 144 |     std::string_view metadata; | 
| Jason M. Bills | 16428a1 | 2018-11-02 12:42:29 -0700 | [diff] [blame] | 145 |     // Get the metadata from the requested field of the journal entry | 
 | 146 |     ret = getJournalMetadata(journal, field, metadata); | 
 | 147 |     if (ret < 0) | 
 | 148 |     { | 
 | 149 |         return ret; | 
 | 150 |     } | 
| Ed Tanous | b01bf29 | 2019-03-25 19:25:26 +0000 | [diff] [blame] | 151 |     contents = strtol(metadata.data(), nullptr, base); | 
| Jason M. Bills | 16428a1 | 2018-11-02 12:42:29 -0700 | [diff] [blame] | 152 |     return ret; | 
 | 153 | } | 
 | 154 |  | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 155 | inline static bool getEntryTimestamp(sd_journal* journal, | 
 | 156 |                                      std::string& entryTimestamp) | 
| ZhikuiRen | a3316fc | 2020-01-29 14:58:08 -0800 | [diff] [blame] | 157 | { | 
 | 158 |     int ret = 0; | 
 | 159 |     uint64_t timestamp = 0; | 
 | 160 |     ret = sd_journal_get_realtime_usec(journal, ×tamp); | 
 | 161 |     if (ret < 0) | 
 | 162 |     { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 163 |         BMCWEB_LOG_ERROR("Failed to read entry timestamp: {}", strerror(-ret)); | 
| ZhikuiRen | a3316fc | 2020-01-29 14:58:08 -0800 | [diff] [blame] | 164 |         return false; | 
 | 165 |     } | 
| Konstantin Aladyshev | e645c5e | 2023-02-17 13:09:53 +0300 | [diff] [blame] | 166 |     entryTimestamp = redfish::time_utils::getDateTimeUintUs(timestamp); | 
| Asmitha Karunanithi | 9c620e2 | 2020-08-02 11:55:21 -0500 | [diff] [blame] | 167 |     return true; | 
| ZhikuiRen | a3316fc | 2020-01-29 14:58:08 -0800 | [diff] [blame] | 168 | } | 
| Ed Tanous | 50b8a43 | 2022-02-03 16:29:50 -0800 | [diff] [blame] | 169 |  | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 170 | inline static bool getUniqueEntryID(sd_journal* journal, std::string& entryID, | 
 | 171 |                                     const bool firstEntry = true) | 
| Jason M. Bills | 16428a1 | 2018-11-02 12:42:29 -0700 | [diff] [blame] | 172 | { | 
 | 173 |     int ret = 0; | 
 | 174 |     static uint64_t prevTs = 0; | 
 | 175 |     static int index = 0; | 
| Jason M. Bills | e85d6b1 | 2019-07-29 17:01:15 -0700 | [diff] [blame] | 176 |     if (firstEntry) | 
 | 177 |     { | 
 | 178 |         prevTs = 0; | 
 | 179 |     } | 
 | 180 |  | 
| Jason M. Bills | 16428a1 | 2018-11-02 12:42:29 -0700 | [diff] [blame] | 181 |     // Get the entry timestamp | 
 | 182 |     uint64_t curTs = 0; | 
 | 183 |     ret = sd_journal_get_realtime_usec(journal, &curTs); | 
 | 184 |     if (ret < 0) | 
 | 185 |     { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 186 |         BMCWEB_LOG_ERROR("Failed to read entry timestamp: {}", strerror(-ret)); | 
| Jason M. Bills | 16428a1 | 2018-11-02 12:42:29 -0700 | [diff] [blame] | 187 |         return false; | 
 | 188 |     } | 
 | 189 |     // If the timestamp isn't unique, increment the index | 
 | 190 |     if (curTs == prevTs) | 
 | 191 |     { | 
 | 192 |         index++; | 
 | 193 |     } | 
 | 194 |     else | 
 | 195 |     { | 
 | 196 |         // Otherwise, reset it | 
 | 197 |         index = 0; | 
 | 198 |     } | 
 | 199 |     // Save the timestamp | 
 | 200 |     prevTs = curTs; | 
 | 201 |  | 
 | 202 |     entryID = std::to_string(curTs); | 
 | 203 |     if (index > 0) | 
 | 204 |     { | 
 | 205 |         entryID += "_" + std::to_string(index); | 
 | 206 |     } | 
 | 207 |     return true; | 
 | 208 | } | 
 | 209 |  | 
| Gunnar Mills | 1214b7e | 2020-06-04 10:11:30 -0500 | [diff] [blame] | 210 | static bool getUniqueEntryID(const std::string& logEntry, std::string& entryID, | 
| Jason M. Bills | e85d6b1 | 2019-07-29 17:01:15 -0700 | [diff] [blame] | 211 |                              const bool firstEntry = true) | 
| Jason M. Bills | 9582018 | 2019-04-22 16:25:34 -0700 | [diff] [blame] | 212 | { | 
| Ed Tanous | 271584a | 2019-07-09 16:24:22 -0700 | [diff] [blame] | 213 |     static time_t prevTs = 0; | 
| Jason M. Bills | 9582018 | 2019-04-22 16:25:34 -0700 | [diff] [blame] | 214 |     static int index = 0; | 
| Jason M. Bills | e85d6b1 | 2019-07-29 17:01:15 -0700 | [diff] [blame] | 215 |     if (firstEntry) | 
 | 216 |     { | 
 | 217 |         prevTs = 0; | 
 | 218 |     } | 
 | 219 |  | 
| Jason M. Bills | 9582018 | 2019-04-22 16:25:34 -0700 | [diff] [blame] | 220 |     // Get the entry timestamp | 
| Ed Tanous | 271584a | 2019-07-09 16:24:22 -0700 | [diff] [blame] | 221 |     std::time_t curTs = 0; | 
| Jason M. Bills | 9582018 | 2019-04-22 16:25:34 -0700 | [diff] [blame] | 222 |     std::tm timeStruct = {}; | 
 | 223 |     std::istringstream entryStream(logEntry); | 
 | 224 |     if (entryStream >> std::get_time(&timeStruct, "%Y-%m-%dT%H:%M:%S")) | 
 | 225 |     { | 
 | 226 |         curTs = std::mktime(&timeStruct); | 
 | 227 |     } | 
 | 228 |     // If the timestamp isn't unique, increment the index | 
 | 229 |     if (curTs == prevTs) | 
 | 230 |     { | 
 | 231 |         index++; | 
 | 232 |     } | 
 | 233 |     else | 
 | 234 |     { | 
 | 235 |         // Otherwise, reset it | 
 | 236 |         index = 0; | 
 | 237 |     } | 
 | 238 |     // Save the timestamp | 
 | 239 |     prevTs = curTs; | 
 | 240 |  | 
 | 241 |     entryID = std::to_string(curTs); | 
 | 242 |     if (index > 0) | 
 | 243 |     { | 
 | 244 |         entryID += "_" + std::to_string(index); | 
 | 245 |     } | 
 | 246 |     return true; | 
 | 247 | } | 
 | 248 |  | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 249 | inline static bool | 
| zhanghch05 | 8d1b46d | 2021-04-01 11:18:24 +0800 | [diff] [blame] | 250 |     getTimestampFromID(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 251 |                        const std::string& entryID, uint64_t& timestamp, | 
 | 252 |                        uint64_t& index) | 
| Jason M. Bills | 16428a1 | 2018-11-02 12:42:29 -0700 | [diff] [blame] | 253 | { | 
 | 254 |     if (entryID.empty()) | 
 | 255 |     { | 
 | 256 |         return false; | 
 | 257 |     } | 
 | 258 |     // Convert the unique ID back to a timestamp to find the entry | 
| Ed Tanous | 39e7750 | 2019-03-04 17:35:53 -0800 | [diff] [blame] | 259 |     std::string_view tsStr(entryID); | 
| Jason M. Bills | 16428a1 | 2018-11-02 12:42:29 -0700 | [diff] [blame] | 260 |  | 
| Ed Tanous | 81ce609 | 2020-12-17 16:54:55 +0000 | [diff] [blame] | 261 |     auto underscorePos = tsStr.find('_'); | 
| Ed Tanous | 71d5d8d | 2022-01-25 11:04:33 -0800 | [diff] [blame] | 262 |     if (underscorePos != std::string_view::npos) | 
| Jason M. Bills | 16428a1 | 2018-11-02 12:42:29 -0700 | [diff] [blame] | 263 |     { | 
 | 264 |         // Timestamp has an index | 
 | 265 |         tsStr.remove_suffix(tsStr.size() - underscorePos); | 
| Ed Tanous | 39e7750 | 2019-03-04 17:35:53 -0800 | [diff] [blame] | 266 |         std::string_view indexStr(entryID); | 
| Jason M. Bills | 16428a1 | 2018-11-02 12:42:29 -0700 | [diff] [blame] | 267 |         indexStr.remove_prefix(underscorePos + 1); | 
| Patrick Williams | 84396af | 2023-05-11 11:47:45 -0500 | [diff] [blame] | 268 |         auto [ptr, ec] = std::from_chars(indexStr.begin(), indexStr.end(), | 
 | 269 |                                          index); | 
| Ed Tanous | c0bd5e4 | 2021-09-13 17:00:19 -0700 | [diff] [blame] | 270 |         if (ec != std::errc()) | 
| Jason M. Bills | 16428a1 | 2018-11-02 12:42:29 -0700 | [diff] [blame] | 271 |         { | 
| Jiaqing Zhao | 9db4ba2 | 2022-10-09 17:24:40 +0800 | [diff] [blame] | 272 |             messages::resourceNotFound(asyncResp->res, "LogEntry", entryID); | 
| Jason M. Bills | 16428a1 | 2018-11-02 12:42:29 -0700 | [diff] [blame] | 273 |             return false; | 
 | 274 |         } | 
 | 275 |     } | 
 | 276 |     // Timestamp has no index | 
| Patrick Williams | 84396af | 2023-05-11 11:47:45 -0500 | [diff] [blame] | 277 |     auto [ptr, ec] = std::from_chars(tsStr.begin(), tsStr.end(), timestamp); | 
| Ed Tanous | c0bd5e4 | 2021-09-13 17:00:19 -0700 | [diff] [blame] | 278 |     if (ec != std::errc()) | 
| Jason M. Bills | 16428a1 | 2018-11-02 12:42:29 -0700 | [diff] [blame] | 279 |     { | 
| Jiaqing Zhao | 9db4ba2 | 2022-10-09 17:24:40 +0800 | [diff] [blame] | 280 |         messages::resourceNotFound(asyncResp->res, "LogEntry", entryID); | 
| Jason M. Bills | 16428a1 | 2018-11-02 12:42:29 -0700 | [diff] [blame] | 281 |         return false; | 
 | 282 |     } | 
 | 283 |     return true; | 
 | 284 | } | 
 | 285 |  | 
| Jason M. Bills | 9582018 | 2019-04-22 16:25:34 -0700 | [diff] [blame] | 286 | static bool | 
| Gunnar Mills | 1214b7e | 2020-06-04 10:11:30 -0500 | [diff] [blame] | 287 |     getRedfishLogFiles(std::vector<std::filesystem::path>& redfishLogFiles) | 
| Jason M. Bills | 9582018 | 2019-04-22 16:25:34 -0700 | [diff] [blame] | 288 | { | 
 | 289 |     static const std::filesystem::path redfishLogDir = "/var/log"; | 
 | 290 |     static const std::string redfishLogFilename = "redfish"; | 
 | 291 |  | 
 | 292 |     // Loop through the directory looking for redfish log files | 
| Gunnar Mills | 1214b7e | 2020-06-04 10:11:30 -0500 | [diff] [blame] | 293 |     for (const std::filesystem::directory_entry& dirEnt : | 
| Jason M. Bills | 9582018 | 2019-04-22 16:25:34 -0700 | [diff] [blame] | 294 |          std::filesystem::directory_iterator(redfishLogDir)) | 
 | 295 |     { | 
 | 296 |         // If we find a redfish log file, save the path | 
 | 297 |         std::string filename = dirEnt.path().filename(); | 
| Ed Tanous | 11ba397 | 2022-07-11 09:50:41 -0700 | [diff] [blame] | 298 |         if (filename.starts_with(redfishLogFilename)) | 
| Jason M. Bills | 9582018 | 2019-04-22 16:25:34 -0700 | [diff] [blame] | 299 |         { | 
 | 300 |             redfishLogFiles.emplace_back(redfishLogDir / filename); | 
 | 301 |         } | 
 | 302 |     } | 
 | 303 |     // As the log files rotate, they are appended with a ".#" that is higher for | 
 | 304 |     // the older logs. Since we don't expect more than 10 log files, we | 
 | 305 |     // can just sort the list to get them in order from newest to oldest | 
| Ed Tanous | 3544d2a | 2023-08-06 18:12:20 -0700 | [diff] [blame] | 306 |     std::ranges::sort(redfishLogFiles); | 
| Jason M. Bills | 9582018 | 2019-04-22 16:25:34 -0700 | [diff] [blame] | 307 |  | 
 | 308 |     return !redfishLogFiles.empty(); | 
 | 309 | } | 
 | 310 |  | 
| Asmitha Karunanithi | 68dd075 | 2022-11-15 11:33:46 -0600 | [diff] [blame] | 311 | inline log_entry::OriginatorTypes | 
 | 312 |     mapDbusOriginatorTypeToRedfish(const std::string& originatorType) | 
 | 313 | { | 
 | 314 |     if (originatorType == | 
 | 315 |         "xyz.openbmc_project.Common.OriginatedBy.OriginatorTypes.Client") | 
 | 316 |     { | 
 | 317 |         return log_entry::OriginatorTypes::Client; | 
 | 318 |     } | 
 | 319 |     if (originatorType == | 
 | 320 |         "xyz.openbmc_project.Common.OriginatedBy.OriginatorTypes.Internal") | 
 | 321 |     { | 
 | 322 |         return log_entry::OriginatorTypes::Internal; | 
 | 323 |     } | 
 | 324 |     if (originatorType == | 
 | 325 |         "xyz.openbmc_project.Common.OriginatedBy.OriginatorTypes.SupportingService") | 
 | 326 |     { | 
 | 327 |         return log_entry::OriginatorTypes::SupportingService; | 
 | 328 |     } | 
 | 329 |     return log_entry::OriginatorTypes::Invalid; | 
 | 330 | } | 
 | 331 |  | 
| Claire Weinan | aefe378 | 2022-07-15 19:17:19 -0700 | [diff] [blame] | 332 | inline void parseDumpEntryFromDbusObject( | 
| Jiaqing Zhao | 2d613eb | 2022-08-15 16:03:00 +0800 | [diff] [blame] | 333 |     const dbus::utility::ManagedObjectType::value_type& object, | 
| Claire Weinan | c6fecda | 2022-07-15 10:43:25 -0700 | [diff] [blame] | 334 |     std::string& dumpStatus, uint64_t& size, uint64_t& timestampUs, | 
| Asmitha Karunanithi | 68dd075 | 2022-11-15 11:33:46 -0600 | [diff] [blame] | 335 |     std::string& originatorId, log_entry::OriginatorTypes& originatorType, | 
| Claire Weinan | aefe378 | 2022-07-15 19:17:19 -0700 | [diff] [blame] | 336 |     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) | 
 | 337 | { | 
 | 338 |     for (const auto& interfaceMap : object.second) | 
 | 339 |     { | 
 | 340 |         if (interfaceMap.first == "xyz.openbmc_project.Common.Progress") | 
 | 341 |         { | 
 | 342 |             for (const auto& propertyMap : interfaceMap.second) | 
 | 343 |             { | 
 | 344 |                 if (propertyMap.first == "Status") | 
 | 345 |                 { | 
 | 346 |                     const auto* status = | 
 | 347 |                         std::get_if<std::string>(&propertyMap.second); | 
 | 348 |                     if (status == nullptr) | 
 | 349 |                     { | 
 | 350 |                         messages::internalError(asyncResp->res); | 
 | 351 |                         break; | 
 | 352 |                     } | 
 | 353 |                     dumpStatus = *status; | 
 | 354 |                 } | 
 | 355 |             } | 
 | 356 |         } | 
 | 357 |         else if (interfaceMap.first == "xyz.openbmc_project.Dump.Entry") | 
 | 358 |         { | 
 | 359 |             for (const auto& propertyMap : interfaceMap.second) | 
 | 360 |             { | 
 | 361 |                 if (propertyMap.first == "Size") | 
 | 362 |                 { | 
 | 363 |                     const auto* sizePtr = | 
 | 364 |                         std::get_if<uint64_t>(&propertyMap.second); | 
 | 365 |                     if (sizePtr == nullptr) | 
 | 366 |                     { | 
 | 367 |                         messages::internalError(asyncResp->res); | 
 | 368 |                         break; | 
 | 369 |                     } | 
 | 370 |                     size = *sizePtr; | 
 | 371 |                     break; | 
 | 372 |                 } | 
 | 373 |             } | 
 | 374 |         } | 
 | 375 |         else if (interfaceMap.first == "xyz.openbmc_project.Time.EpochTime") | 
 | 376 |         { | 
 | 377 |             for (const auto& propertyMap : interfaceMap.second) | 
 | 378 |             { | 
 | 379 |                 if (propertyMap.first == "Elapsed") | 
 | 380 |                 { | 
 | 381 |                     const uint64_t* usecsTimeStamp = | 
 | 382 |                         std::get_if<uint64_t>(&propertyMap.second); | 
 | 383 |                     if (usecsTimeStamp == nullptr) | 
 | 384 |                     { | 
 | 385 |                         messages::internalError(asyncResp->res); | 
 | 386 |                         break; | 
 | 387 |                     } | 
| Claire Weinan | c6fecda | 2022-07-15 10:43:25 -0700 | [diff] [blame] | 388 |                     timestampUs = *usecsTimeStamp; | 
| Claire Weinan | aefe378 | 2022-07-15 19:17:19 -0700 | [diff] [blame] | 389 |                     break; | 
 | 390 |                 } | 
 | 391 |             } | 
 | 392 |         } | 
| Asmitha Karunanithi | 68dd075 | 2022-11-15 11:33:46 -0600 | [diff] [blame] | 393 |         else if (interfaceMap.first == | 
 | 394 |                  "xyz.openbmc_project.Common.OriginatedBy") | 
 | 395 |         { | 
 | 396 |             for (const auto& propertyMap : interfaceMap.second) | 
 | 397 |             { | 
 | 398 |                 if (propertyMap.first == "OriginatorId") | 
 | 399 |                 { | 
 | 400 |                     const std::string* id = | 
 | 401 |                         std::get_if<std::string>(&propertyMap.second); | 
 | 402 |                     if (id == nullptr) | 
 | 403 |                     { | 
 | 404 |                         messages::internalError(asyncResp->res); | 
 | 405 |                         break; | 
 | 406 |                     } | 
 | 407 |                     originatorId = *id; | 
 | 408 |                 } | 
 | 409 |  | 
 | 410 |                 if (propertyMap.first == "OriginatorType") | 
 | 411 |                 { | 
 | 412 |                     const std::string* type = | 
 | 413 |                         std::get_if<std::string>(&propertyMap.second); | 
 | 414 |                     if (type == nullptr) | 
 | 415 |                     { | 
 | 416 |                         messages::internalError(asyncResp->res); | 
 | 417 |                         break; | 
 | 418 |                     } | 
 | 419 |  | 
 | 420 |                     originatorType = mapDbusOriginatorTypeToRedfish(*type); | 
 | 421 |                     if (originatorType == log_entry::OriginatorTypes::Invalid) | 
 | 422 |                     { | 
 | 423 |                         messages::internalError(asyncResp->res); | 
 | 424 |                         break; | 
 | 425 |                     } | 
 | 426 |                 } | 
 | 427 |             } | 
 | 428 |         } | 
| Claire Weinan | aefe378 | 2022-07-15 19:17:19 -0700 | [diff] [blame] | 429 |     } | 
 | 430 | } | 
 | 431 |  | 
| Nan Zhou | 21ab404 | 2022-06-26 23:07:40 +0000 | [diff] [blame] | 432 | static std::string getDumpEntriesPath(const std::string& dumpType) | 
| Claire Weinan | fdd2690 | 2022-03-01 14:18:25 -0800 | [diff] [blame] | 433 | { | 
 | 434 |     std::string entriesPath; | 
 | 435 |  | 
 | 436 |     if (dumpType == "BMC") | 
 | 437 |     { | 
 | 438 |         entriesPath = "/redfish/v1/Managers/bmc/LogServices/Dump/Entries/"; | 
 | 439 |     } | 
 | 440 |     else if (dumpType == "FaultLog") | 
 | 441 |     { | 
 | 442 |         entriesPath = "/redfish/v1/Managers/bmc/LogServices/FaultLog/Entries/"; | 
 | 443 |     } | 
 | 444 |     else if (dumpType == "System") | 
 | 445 |     { | 
 | 446 |         entriesPath = "/redfish/v1/Systems/system/LogServices/Dump/Entries/"; | 
 | 447 |     } | 
 | 448 |     else | 
 | 449 |     { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 450 |         BMCWEB_LOG_ERROR("getDumpEntriesPath() invalid dump type: {}", | 
 | 451 |                          dumpType); | 
| Claire Weinan | fdd2690 | 2022-03-01 14:18:25 -0800 | [diff] [blame] | 452 |     } | 
 | 453 |  | 
 | 454 |     // Returns empty string on error | 
 | 455 |     return entriesPath; | 
 | 456 | } | 
 | 457 |  | 
| zhanghch05 | 8d1b46d | 2021-04-01 11:18:24 +0800 | [diff] [blame] | 458 | inline void | 
 | 459 |     getDumpEntryCollection(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 460 |                            const std::string& dumpType) | 
| Asmitha Karunanithi | 5cb1dd2 | 2020-05-07 04:35:02 -0500 | [diff] [blame] | 461 | { | 
| Claire Weinan | fdd2690 | 2022-03-01 14:18:25 -0800 | [diff] [blame] | 462 |     std::string entriesPath = getDumpEntriesPath(dumpType); | 
 | 463 |     if (entriesPath.empty()) | 
| Asmitha Karunanithi | 5cb1dd2 | 2020-05-07 04:35:02 -0500 | [diff] [blame] | 464 |     { | 
| Asmitha Karunanithi | 5cb1dd2 | 2020-05-07 04:35:02 -0500 | [diff] [blame] | 465 |         messages::internalError(asyncResp->res); | 
 | 466 |         return; | 
 | 467 |     } | 
 | 468 |  | 
| George Liu | 5eb468d | 2023-06-20 17:03:24 +0800 | [diff] [blame] | 469 |     sdbusplus::message::object_path path("/xyz/openbmc_project/dump"); | 
 | 470 |     dbus::utility::getManagedObjects( | 
 | 471 |         "xyz.openbmc_project.Dump.Manager", path, | 
| Claire Weinan | fdd2690 | 2022-03-01 14:18:25 -0800 | [diff] [blame] | 472 |         [asyncResp, entriesPath, | 
| Ed Tanous | 5e7e2dc | 2023-02-16 10:37:01 -0800 | [diff] [blame] | 473 |          dumpType](const boost::system::error_code& ec, | 
| George Liu | 5eb468d | 2023-06-20 17:03:24 +0800 | [diff] [blame] | 474 |                    const dbus::utility::ManagedObjectType& objects) { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 475 |         if (ec) | 
 | 476 |         { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 477 |             BMCWEB_LOG_ERROR("DumpEntry resp_handler got error {}", ec); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 478 |             messages::internalError(asyncResp->res); | 
 | 479 |             return; | 
 | 480 |         } | 
 | 481 |  | 
| Claire Weinan | fdd2690 | 2022-03-01 14:18:25 -0800 | [diff] [blame] | 482 |         // Remove ending slash | 
 | 483 |         std::string odataIdStr = entriesPath; | 
 | 484 |         if (!odataIdStr.empty()) | 
 | 485 |         { | 
 | 486 |             odataIdStr.pop_back(); | 
 | 487 |         } | 
 | 488 |  | 
 | 489 |         asyncResp->res.jsonValue["@odata.type"] = | 
 | 490 |             "#LogEntryCollection.LogEntryCollection"; | 
 | 491 |         asyncResp->res.jsonValue["@odata.id"] = std::move(odataIdStr); | 
 | 492 |         asyncResp->res.jsonValue["Name"] = dumpType + " Dump Entries"; | 
| Patrick Williams | 89492a1 | 2023-05-10 07:51:34 -0500 | [diff] [blame] | 493 |         asyncResp->res.jsonValue["Description"] = "Collection of " + dumpType + | 
 | 494 |                                                   " Dump Entries"; | 
| Claire Weinan | fdd2690 | 2022-03-01 14:18:25 -0800 | [diff] [blame] | 495 |  | 
| Ed Tanous | 3544d2a | 2023-08-06 18:12:20 -0700 | [diff] [blame] | 496 |         nlohmann::json::array_t entriesArray; | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 497 |         std::string dumpEntryPath = | 
 | 498 |             "/xyz/openbmc_project/dump/" + | 
 | 499 |             std::string(boost::algorithm::to_lower_copy(dumpType)) + "/entry/"; | 
 | 500 |  | 
| George Liu | 5eb468d | 2023-06-20 17:03:24 +0800 | [diff] [blame] | 501 |         dbus::utility::ManagedObjectType resp(objects); | 
| Ed Tanous | 3544d2a | 2023-08-06 18:12:20 -0700 | [diff] [blame] | 502 |         std::ranges::sort(resp, [](const auto& l, const auto& r) { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 503 |             return AlphanumLess<std::string>()(l.first.filename(), | 
 | 504 |                                                r.first.filename()); | 
 | 505 |         }); | 
 | 506 |  | 
 | 507 |         for (auto& object : resp) | 
 | 508 |         { | 
 | 509 |             if (object.first.str.find(dumpEntryPath) == std::string::npos) | 
| Asmitha Karunanithi | 5cb1dd2 | 2020-05-07 04:35:02 -0500 | [diff] [blame] | 510 |             { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 511 |                 continue; | 
 | 512 |             } | 
| Claire Weinan | c6fecda | 2022-07-15 10:43:25 -0700 | [diff] [blame] | 513 |             uint64_t timestampUs = 0; | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 514 |             uint64_t size = 0; | 
 | 515 |             std::string dumpStatus; | 
| Asmitha Karunanithi | 68dd075 | 2022-11-15 11:33:46 -0600 | [diff] [blame] | 516 |             std::string originatorId; | 
 | 517 |             log_entry::OriginatorTypes originatorType = | 
 | 518 |                 log_entry::OriginatorTypes::Internal; | 
| Jason M. Bills | 433b68b | 2022-06-28 12:24:26 -0700 | [diff] [blame] | 519 |             nlohmann::json::object_t thisEntry; | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 520 |  | 
 | 521 |             std::string entryID = object.first.filename(); | 
 | 522 |             if (entryID.empty()) | 
 | 523 |             { | 
 | 524 |                 continue; | 
| Asmitha Karunanithi | 5cb1dd2 | 2020-05-07 04:35:02 -0500 | [diff] [blame] | 525 |             } | 
 | 526 |  | 
| Claire Weinan | c6fecda | 2022-07-15 10:43:25 -0700 | [diff] [blame] | 527 |             parseDumpEntryFromDbusObject(object, dumpStatus, size, timestampUs, | 
| Asmitha Karunanithi | 68dd075 | 2022-11-15 11:33:46 -0600 | [diff] [blame] | 528 |                                          originatorId, originatorType, | 
| Claire Weinan | aefe378 | 2022-07-15 19:17:19 -0700 | [diff] [blame] | 529 |                                          asyncResp); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 530 |  | 
 | 531 |             if (dumpStatus != | 
 | 532 |                     "xyz.openbmc_project.Common.Progress.OperationStatus.Completed" && | 
 | 533 |                 !dumpStatus.empty()) | 
 | 534 |             { | 
 | 535 |                 // Dump status is not Complete, no need to enumerate | 
 | 536 |                 continue; | 
 | 537 |             } | 
 | 538 |  | 
| Asmitha Karunanithi | 68dd075 | 2022-11-15 11:33:46 -0600 | [diff] [blame] | 539 |             thisEntry["@odata.type"] = "#LogEntry.v1_11_0.LogEntry"; | 
| Claire Weinan | fdd2690 | 2022-03-01 14:18:25 -0800 | [diff] [blame] | 540 |             thisEntry["@odata.id"] = entriesPath + entryID; | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 541 |             thisEntry["Id"] = entryID; | 
 | 542 |             thisEntry["EntryType"] = "Event"; | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 543 |             thisEntry["Name"] = dumpType + " Dump Entry"; | 
| Claire Weinan | bbd80db | 2022-10-26 16:55:52 -0700 | [diff] [blame] | 544 |             thisEntry["Created"] = | 
 | 545 |                 redfish::time_utils::getDateTimeUintUs(timestampUs); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 546 |  | 
| Asmitha Karunanithi | 68dd075 | 2022-11-15 11:33:46 -0600 | [diff] [blame] | 547 |             if (!originatorId.empty()) | 
 | 548 |             { | 
 | 549 |                 thisEntry["Originator"] = originatorId; | 
 | 550 |                 thisEntry["OriginatorType"] = originatorType; | 
 | 551 |             } | 
 | 552 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 553 |             if (dumpType == "BMC") | 
 | 554 |             { | 
 | 555 |                 thisEntry["DiagnosticDataType"] = "Manager"; | 
| Patrick Williams | 89492a1 | 2023-05-10 07:51:34 -0500 | [diff] [blame] | 556 |                 thisEntry["AdditionalDataURI"] = entriesPath + entryID + | 
 | 557 |                                                  "/attachment"; | 
| Claire Weinan | fdd2690 | 2022-03-01 14:18:25 -0800 | [diff] [blame] | 558 |                 thisEntry["AdditionalDataSizeBytes"] = size; | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 559 |             } | 
 | 560 |             else if (dumpType == "System") | 
 | 561 |             { | 
 | 562 |                 thisEntry["DiagnosticDataType"] = "OEM"; | 
 | 563 |                 thisEntry["OEMDiagnosticDataType"] = "System"; | 
| Patrick Williams | 89492a1 | 2023-05-10 07:51:34 -0500 | [diff] [blame] | 564 |                 thisEntry["AdditionalDataURI"] = entriesPath + entryID + | 
 | 565 |                                                  "/attachment"; | 
| Claire Weinan | fdd2690 | 2022-03-01 14:18:25 -0800 | [diff] [blame] | 566 |                 thisEntry["AdditionalDataSizeBytes"] = size; | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 567 |             } | 
| Patrick Williams | b2ba307 | 2023-05-12 10:27:39 -0500 | [diff] [blame] | 568 |             entriesArray.emplace_back(std::move(thisEntry)); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 569 |         } | 
 | 570 |         asyncResp->res.jsonValue["Members@odata.count"] = entriesArray.size(); | 
| Ed Tanous | 3544d2a | 2023-08-06 18:12:20 -0700 | [diff] [blame] | 571 |         asyncResp->res.jsonValue["Members"] = std::move(entriesArray); | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 572 |     }); | 
| Asmitha Karunanithi | 5cb1dd2 | 2020-05-07 04:35:02 -0500 | [diff] [blame] | 573 | } | 
 | 574 |  | 
| zhanghch05 | 8d1b46d | 2021-04-01 11:18:24 +0800 | [diff] [blame] | 575 | inline void | 
| Claire Weinan | c7a6d66 | 2022-06-13 16:36:39 -0700 | [diff] [blame] | 576 |     getDumpEntryById(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
| zhanghch05 | 8d1b46d | 2021-04-01 11:18:24 +0800 | [diff] [blame] | 577 |                      const std::string& entryID, const std::string& dumpType) | 
| Asmitha Karunanithi | 5cb1dd2 | 2020-05-07 04:35:02 -0500 | [diff] [blame] | 578 | { | 
| Claire Weinan | fdd2690 | 2022-03-01 14:18:25 -0800 | [diff] [blame] | 579 |     std::string entriesPath = getDumpEntriesPath(dumpType); | 
 | 580 |     if (entriesPath.empty()) | 
| Asmitha Karunanithi | 5cb1dd2 | 2020-05-07 04:35:02 -0500 | [diff] [blame] | 581 |     { | 
| Asmitha Karunanithi | 5cb1dd2 | 2020-05-07 04:35:02 -0500 | [diff] [blame] | 582 |         messages::internalError(asyncResp->res); | 
 | 583 |         return; | 
 | 584 |     } | 
 | 585 |  | 
| George Liu | 5eb468d | 2023-06-20 17:03:24 +0800 | [diff] [blame] | 586 |     sdbusplus::message::object_path path("/xyz/openbmc_project/dump"); | 
 | 587 |     dbus::utility::getManagedObjects( | 
 | 588 |         "xyz.openbmc_project.Dump.Manager", path, | 
| Claire Weinan | fdd2690 | 2022-03-01 14:18:25 -0800 | [diff] [blame] | 589 |         [asyncResp, entryID, dumpType, | 
| Ed Tanous | 5e7e2dc | 2023-02-16 10:37:01 -0800 | [diff] [blame] | 590 |          entriesPath](const boost::system::error_code& ec, | 
| Ed Tanous | 02cad96 | 2022-06-30 16:50:15 -0700 | [diff] [blame] | 591 |                       const dbus::utility::ManagedObjectType& resp) { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 592 |         if (ec) | 
 | 593 |         { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 594 |             BMCWEB_LOG_ERROR("DumpEntry resp_handler got error {}", ec); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 595 |             messages::internalError(asyncResp->res); | 
 | 596 |             return; | 
 | 597 |         } | 
 | 598 |  | 
 | 599 |         bool foundDumpEntry = false; | 
 | 600 |         std::string dumpEntryPath = | 
 | 601 |             "/xyz/openbmc_project/dump/" + | 
 | 602 |             std::string(boost::algorithm::to_lower_copy(dumpType)) + "/entry/"; | 
 | 603 |  | 
 | 604 |         for (const auto& objectPath : resp) | 
 | 605 |         { | 
 | 606 |             if (objectPath.first.str != dumpEntryPath + entryID) | 
| Asmitha Karunanithi | 5cb1dd2 | 2020-05-07 04:35:02 -0500 | [diff] [blame] | 607 |             { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 608 |                 continue; | 
 | 609 |             } | 
 | 610 |  | 
 | 611 |             foundDumpEntry = true; | 
| Claire Weinan | c6fecda | 2022-07-15 10:43:25 -0700 | [diff] [blame] | 612 |             uint64_t timestampUs = 0; | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 613 |             uint64_t size = 0; | 
 | 614 |             std::string dumpStatus; | 
| Asmitha Karunanithi | 68dd075 | 2022-11-15 11:33:46 -0600 | [diff] [blame] | 615 |             std::string originatorId; | 
 | 616 |             log_entry::OriginatorTypes originatorType = | 
 | 617 |                 log_entry::OriginatorTypes::Internal; | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 618 |  | 
| Claire Weinan | aefe378 | 2022-07-15 19:17:19 -0700 | [diff] [blame] | 619 |             parseDumpEntryFromDbusObject(objectPath, dumpStatus, size, | 
| Asmitha Karunanithi | 68dd075 | 2022-11-15 11:33:46 -0600 | [diff] [blame] | 620 |                                          timestampUs, originatorId, | 
 | 621 |                                          originatorType, asyncResp); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 622 |  | 
 | 623 |             if (dumpStatus != | 
 | 624 |                     "xyz.openbmc_project.Common.Progress.OperationStatus.Completed" && | 
 | 625 |                 !dumpStatus.empty()) | 
 | 626 |             { | 
 | 627 |                 // Dump status is not Complete | 
 | 628 |                 // return not found until status is changed to Completed | 
| Krzysztof Grobelny | d1bde9e | 2022-09-07 10:40:51 +0200 | [diff] [blame] | 629 |                 messages::resourceNotFound(asyncResp->res, dumpType + " dump", | 
 | 630 |                                            entryID); | 
| Asmitha Karunanithi | 5cb1dd2 | 2020-05-07 04:35:02 -0500 | [diff] [blame] | 631 |                 return; | 
 | 632 |             } | 
 | 633 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 634 |             asyncResp->res.jsonValue["@odata.type"] = | 
| Asmitha Karunanithi | 68dd075 | 2022-11-15 11:33:46 -0600 | [diff] [blame] | 635 |                 "#LogEntry.v1_11_0.LogEntry"; | 
| Claire Weinan | fdd2690 | 2022-03-01 14:18:25 -0800 | [diff] [blame] | 636 |             asyncResp->res.jsonValue["@odata.id"] = entriesPath + entryID; | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 637 |             asyncResp->res.jsonValue["Id"] = entryID; | 
 | 638 |             asyncResp->res.jsonValue["EntryType"] = "Event"; | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 639 |             asyncResp->res.jsonValue["Name"] = dumpType + " Dump Entry"; | 
| Claire Weinan | bbd80db | 2022-10-26 16:55:52 -0700 | [diff] [blame] | 640 |             asyncResp->res.jsonValue["Created"] = | 
 | 641 |                 redfish::time_utils::getDateTimeUintUs(timestampUs); | 
| Asmitha Karunanithi | b47452b | 2020-09-25 02:02:19 -0500 | [diff] [blame] | 642 |  | 
| Asmitha Karunanithi | 68dd075 | 2022-11-15 11:33:46 -0600 | [diff] [blame] | 643 |             if (!originatorId.empty()) | 
 | 644 |             { | 
 | 645 |                 asyncResp->res.jsonValue["Originator"] = originatorId; | 
 | 646 |                 asyncResp->res.jsonValue["OriginatorType"] = originatorType; | 
 | 647 |             } | 
 | 648 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 649 |             if (dumpType == "BMC") | 
| Asmitha Karunanithi | 5cb1dd2 | 2020-05-07 04:35:02 -0500 | [diff] [blame] | 650 |             { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 651 |                 asyncResp->res.jsonValue["DiagnosticDataType"] = "Manager"; | 
 | 652 |                 asyncResp->res.jsonValue["AdditionalDataURI"] = | 
| Claire Weinan | fdd2690 | 2022-03-01 14:18:25 -0800 | [diff] [blame] | 653 |                     entriesPath + entryID + "/attachment"; | 
 | 654 |                 asyncResp->res.jsonValue["AdditionalDataSizeBytes"] = size; | 
| Asmitha Karunanithi | 5cb1dd2 | 2020-05-07 04:35:02 -0500 | [diff] [blame] | 655 |             } | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 656 |             else if (dumpType == "System") | 
| Asmitha Karunanithi | b47452b | 2020-09-25 02:02:19 -0500 | [diff] [blame] | 657 |             { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 658 |                 asyncResp->res.jsonValue["DiagnosticDataType"] = "OEM"; | 
 | 659 |                 asyncResp->res.jsonValue["OEMDiagnosticDataType"] = "System"; | 
 | 660 |                 asyncResp->res.jsonValue["AdditionalDataURI"] = | 
| Claire Weinan | fdd2690 | 2022-03-01 14:18:25 -0800 | [diff] [blame] | 661 |                     entriesPath + entryID + "/attachment"; | 
 | 662 |                 asyncResp->res.jsonValue["AdditionalDataSizeBytes"] = size; | 
| Asmitha Karunanithi | b47452b | 2020-09-25 02:02:19 -0500 | [diff] [blame] | 663 |             } | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 664 |         } | 
 | 665 |         if (!foundDumpEntry) | 
 | 666 |         { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 667 |             BMCWEB_LOG_WARNING("Can't find Dump Entry {}", entryID); | 
| Myung Bae | b90d14f | 2023-05-31 14:40:39 -0500 | [diff] [blame] | 668 |             messages::resourceNotFound(asyncResp->res, dumpType + " dump", | 
 | 669 |                                        entryID); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 670 |             return; | 
 | 671 |         } | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 672 |     }); | 
| Asmitha Karunanithi | 5cb1dd2 | 2020-05-07 04:35:02 -0500 | [diff] [blame] | 673 | } | 
 | 674 |  | 
| zhanghch05 | 8d1b46d | 2021-04-01 11:18:24 +0800 | [diff] [blame] | 675 | inline void deleteDumpEntry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
| Stanley Chu | 9878256 | 2020-11-04 16:10:24 +0800 | [diff] [blame] | 676 |                             const std::string& entryID, | 
| Asmitha Karunanithi | b47452b | 2020-09-25 02:02:19 -0500 | [diff] [blame] | 677 |                             const std::string& dumpType) | 
| Asmitha Karunanithi | 5cb1dd2 | 2020-05-07 04:35:02 -0500 | [diff] [blame] | 678 | { | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 679 |     auto respHandler = [asyncResp, | 
 | 680 |                         entryID](const boost::system::error_code& ec) { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 681 |         BMCWEB_LOG_DEBUG("Dump Entry doDelete callback: Done"); | 
| Asmitha Karunanithi | 5cb1dd2 | 2020-05-07 04:35:02 -0500 | [diff] [blame] | 682 |         if (ec) | 
 | 683 |         { | 
| George Liu | 3de8d8b | 2021-03-22 17:49:39 +0800 | [diff] [blame] | 684 |             if (ec.value() == EBADR) | 
 | 685 |             { | 
 | 686 |                 messages::resourceNotFound(asyncResp->res, "LogEntry", entryID); | 
 | 687 |                 return; | 
 | 688 |             } | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 689 |             BMCWEB_LOG_ERROR( | 
 | 690 |                 "Dump (DBus) doDelete respHandler got error {} entryID={}", ec, | 
 | 691 |                 entryID); | 
| Asmitha Karunanithi | 5cb1dd2 | 2020-05-07 04:35:02 -0500 | [diff] [blame] | 692 |             messages::internalError(asyncResp->res); | 
 | 693 |             return; | 
 | 694 |         } | 
 | 695 |     }; | 
 | 696 |     crow::connections::systemBus->async_method_call( | 
 | 697 |         respHandler, "xyz.openbmc_project.Dump.Manager", | 
| Asmitha Karunanithi | b47452b | 2020-09-25 02:02:19 -0500 | [diff] [blame] | 698 |         "/xyz/openbmc_project/dump/" + | 
 | 699 |             std::string(boost::algorithm::to_lower_copy(dumpType)) + "/entry/" + | 
 | 700 |             entryID, | 
| Asmitha Karunanithi | 5cb1dd2 | 2020-05-07 04:35:02 -0500 | [diff] [blame] | 701 |         "xyz.openbmc_project.Object.Delete", "Delete"); | 
 | 702 | } | 
 | 703 |  | 
| Carson Labrado | 168d1b1 | 2023-03-27 17:04:46 +0000 | [diff] [blame] | 704 | inline void | 
 | 705 |     downloadEntryCallback(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 706 |                           const std::string& entryID, | 
 | 707 |                           const std::string& downloadEntryType, | 
 | 708 |                           const boost::system::error_code& ec, | 
 | 709 |                           const sdbusplus::message::unix_fd& unixfd) | 
 | 710 | { | 
 | 711 |     if (ec.value() == EBADR) | 
 | 712 |     { | 
 | 713 |         messages::resourceNotFound(asyncResp->res, "EntryAttachment", entryID); | 
 | 714 |         return; | 
 | 715 |     } | 
 | 716 |     if (ec) | 
 | 717 |     { | 
 | 718 |         BMCWEB_LOG_ERROR("DBUS response error: {}", ec); | 
 | 719 |         messages::internalError(asyncResp->res); | 
 | 720 |         return; | 
 | 721 |     } | 
 | 722 |  | 
 | 723 |     // Make sure we know how to process the retrieved entry attachment | 
 | 724 |     if ((downloadEntryType != "BMC") && (downloadEntryType != "System")) | 
 | 725 |     { | 
 | 726 |         BMCWEB_LOG_ERROR("downloadEntryCallback() invalid entry type: {}", | 
 | 727 |                          downloadEntryType); | 
 | 728 |         messages::internalError(asyncResp->res); | 
 | 729 |     } | 
 | 730 |  | 
 | 731 |     int fd = -1; | 
 | 732 |     fd = dup(unixfd); | 
 | 733 |     if (fd < 0) | 
 | 734 |     { | 
 | 735 |         BMCWEB_LOG_ERROR("Failed to open file"); | 
 | 736 |         messages::internalError(asyncResp->res); | 
 | 737 |         return; | 
 | 738 |     } | 
 | 739 |  | 
 | 740 |     long long int size = lseek(fd, 0, SEEK_END); | 
 | 741 |     if (size <= 0) | 
 | 742 |     { | 
 | 743 |         BMCWEB_LOG_ERROR("Failed to get size of file, lseek() returned {}", | 
 | 744 |                          size); | 
 | 745 |         messages::internalError(asyncResp->res); | 
 | 746 |         close(fd); | 
 | 747 |         return; | 
 | 748 |     } | 
 | 749 |  | 
 | 750 |     // Arbitrary max size of 20MB to accommodate BMC dumps | 
 | 751 |     constexpr int maxFileSize = 20 * 1024 * 1024; | 
 | 752 |     if (size > maxFileSize) | 
 | 753 |     { | 
 | 754 |         BMCWEB_LOG_ERROR("File size {} exceeds maximum allowed size of {}", | 
 | 755 |                          size, maxFileSize); | 
 | 756 |         messages::internalError(asyncResp->res); | 
 | 757 |         close(fd); | 
 | 758 |         return; | 
 | 759 |     } | 
 | 760 |     long long int rc = lseek(fd, 0, SEEK_SET); | 
 | 761 |     if (rc < 0) | 
 | 762 |     { | 
 | 763 |         BMCWEB_LOG_ERROR("Failed to reset file offset to 0"); | 
 | 764 |         messages::internalError(asyncResp->res); | 
 | 765 |         close(fd); | 
 | 766 |         return; | 
 | 767 |     } | 
 | 768 |  | 
| Ed Tanous | 27b0cf9 | 2023-08-07 12:02:40 -0700 | [diff] [blame] | 769 |     std::string body; | 
 | 770 |     body.resize(static_cast<size_t>(size), '\0'); | 
 | 771 |     rc = read(fd, body.data(), body.size()); | 
| Carson Labrado | 168d1b1 | 2023-03-27 17:04:46 +0000 | [diff] [blame] | 772 |     if ((rc == -1) || (rc != size)) | 
 | 773 |     { | 
 | 774 |         BMCWEB_LOG_ERROR("Failed to read in file"); | 
 | 775 |         messages::internalError(asyncResp->res); | 
 | 776 |         close(fd); | 
 | 777 |         return; | 
 | 778 |     } | 
 | 779 |     close(fd); | 
| Carson Labrado | 168d1b1 | 2023-03-27 17:04:46 +0000 | [diff] [blame] | 780 |     if (downloadEntryType == "System") | 
 | 781 |     { | 
| Ed Tanous | 27b0cf9 | 2023-08-07 12:02:40 -0700 | [diff] [blame] | 782 |         // Base64 encode response. | 
 | 783 |         asyncResp->res.write(crow::utility::base64encode(body)); | 
| Carson Labrado | 168d1b1 | 2023-03-27 17:04:46 +0000 | [diff] [blame] | 784 |         asyncResp->res.addHeader( | 
 | 785 |             boost::beast::http::field::content_transfer_encoding, "Base64"); | 
 | 786 |     } | 
| Ed Tanous | 27b0cf9 | 2023-08-07 12:02:40 -0700 | [diff] [blame] | 787 |     else | 
 | 788 |     { | 
 | 789 |         asyncResp->res.write(std::move(body)); | 
 | 790 |     } | 
| Carson Labrado | 168d1b1 | 2023-03-27 17:04:46 +0000 | [diff] [blame] | 791 |  | 
 | 792 |     asyncResp->res.addHeader(boost::beast::http::field::content_type, | 
 | 793 |                              "application/octet-stream"); | 
 | 794 | } | 
 | 795 |  | 
 | 796 | inline void | 
 | 797 |     downloadDumpEntry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 798 |                       const std::string& entryID, const std::string& dumpType) | 
 | 799 | { | 
 | 800 |     if (dumpType != "BMC") | 
 | 801 |     { | 
 | 802 |         BMCWEB_LOG_WARNING("Can't find Dump Entry {}", entryID); | 
 | 803 |         messages::resourceNotFound(asyncResp->res, dumpType + " dump", entryID); | 
 | 804 |         return; | 
 | 805 |     } | 
 | 806 |  | 
 | 807 |     std::string dumpEntryPath = | 
 | 808 |         sdbusplus::message::object_path("/xyz/openbmc_project/dump/") / | 
 | 809 |         std::string(boost::algorithm::to_lower_copy(dumpType)) / "entry" / | 
 | 810 |         entryID; | 
 | 811 |  | 
 | 812 |     auto downloadDumpEntryHandler = | 
 | 813 |         [asyncResp, entryID, | 
 | 814 |          dumpType](const boost::system::error_code& ec, | 
 | 815 |                    const sdbusplus::message::unix_fd& unixfd) { | 
 | 816 |         downloadEntryCallback(asyncResp, entryID, dumpType, ec, unixfd); | 
 | 817 |     }; | 
 | 818 |  | 
 | 819 |     crow::connections::systemBus->async_method_call( | 
 | 820 |         std::move(downloadDumpEntryHandler), "xyz.openbmc_project.Dump.Manager", | 
 | 821 |         dumpEntryPath, "xyz.openbmc_project.Dump.Entry", "GetFileHandle"); | 
 | 822 | } | 
 | 823 |  | 
 | 824 | inline void | 
 | 825 |     downloadEventLogEntry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 826 |                           const std::string& systemName, | 
 | 827 |                           const std::string& entryID, | 
 | 828 |                           const std::string& dumpType) | 
 | 829 | { | 
 | 830 |     if constexpr (bmcwebEnableMultiHost) | 
 | 831 |     { | 
 | 832 |         // Option currently returns no systems.  TBD | 
 | 833 |         messages::resourceNotFound(asyncResp->res, "ComputerSystem", | 
 | 834 |                                    systemName); | 
 | 835 |         return; | 
 | 836 |     } | 
 | 837 |     if (systemName != "system") | 
 | 838 |     { | 
 | 839 |         messages::resourceNotFound(asyncResp->res, "ComputerSystem", | 
 | 840 |                                    systemName); | 
 | 841 |         return; | 
 | 842 |     } | 
 | 843 |  | 
 | 844 |     std::string entryPath = | 
 | 845 |         sdbusplus::message::object_path("/xyz/openbmc_project/logging/entry") / | 
 | 846 |         entryID; | 
 | 847 |  | 
 | 848 |     auto downloadEventLogEntryHandler = | 
 | 849 |         [asyncResp, entryID, | 
 | 850 |          dumpType](const boost::system::error_code& ec, | 
 | 851 |                    const sdbusplus::message::unix_fd& unixfd) { | 
 | 852 |         downloadEntryCallback(asyncResp, entryID, dumpType, ec, unixfd); | 
 | 853 |     }; | 
 | 854 |  | 
 | 855 |     crow::connections::systemBus->async_method_call( | 
 | 856 |         std::move(downloadEventLogEntryHandler), "xyz.openbmc_project.Logging", | 
 | 857 |         entryPath, "xyz.openbmc_project.Logging.Entry", "GetEntry"); | 
 | 858 | } | 
 | 859 |  | 
| Asmitha Karunanithi | 8e31778 | 2020-12-10 03:35:05 -0600 | [diff] [blame] | 860 | inline DumpCreationProgress | 
 | 861 |     mapDbusStatusToDumpProgress(const std::string& status) | 
| Asmitha Karunanithi | a43be80 | 2020-05-07 05:05:36 -0500 | [diff] [blame] | 862 | { | 
| Asmitha Karunanithi | 8e31778 | 2020-12-10 03:35:05 -0600 | [diff] [blame] | 863 |     if (status == | 
 | 864 |             "xyz.openbmc_project.Common.Progress.OperationStatus.Failed" || | 
 | 865 |         status == "xyz.openbmc_project.Common.Progress.OperationStatus.Aborted") | 
 | 866 |     { | 
 | 867 |         return DumpCreationProgress::DUMP_CREATE_FAILED; | 
 | 868 |     } | 
 | 869 |     if (status == | 
 | 870 |         "xyz.openbmc_project.Common.Progress.OperationStatus.Completed") | 
 | 871 |     { | 
 | 872 |         return DumpCreationProgress::DUMP_CREATE_SUCCESS; | 
 | 873 |     } | 
 | 874 |     return DumpCreationProgress::DUMP_CREATE_INPROGRESS; | 
 | 875 | } | 
 | 876 |  | 
 | 877 | inline DumpCreationProgress | 
 | 878 |     getDumpCompletionStatus(const dbus::utility::DBusPropertiesMap& values) | 
 | 879 | { | 
 | 880 |     for (const auto& [key, val] : values) | 
 | 881 |     { | 
 | 882 |         if (key == "Status") | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 883 |         { | 
| Asmitha Karunanithi | 8e31778 | 2020-12-10 03:35:05 -0600 | [diff] [blame] | 884 |             const std::string* value = std::get_if<std::string>(&val); | 
 | 885 |             if (value == nullptr) | 
 | 886 |             { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 887 |                 BMCWEB_LOG_ERROR("Status property value is null"); | 
| Asmitha Karunanithi | 8e31778 | 2020-12-10 03:35:05 -0600 | [diff] [blame] | 888 |                 return DumpCreationProgress::DUMP_CREATE_FAILED; | 
 | 889 |             } | 
 | 890 |             return mapDbusStatusToDumpProgress(*value); | 
 | 891 |         } | 
 | 892 |     } | 
 | 893 |     return DumpCreationProgress::DUMP_CREATE_INPROGRESS; | 
 | 894 | } | 
 | 895 |  | 
 | 896 | inline std::string getDumpEntryPath(const std::string& dumpPath) | 
 | 897 | { | 
 | 898 |     if (dumpPath == "/xyz/openbmc_project/dump/bmc/entry") | 
 | 899 |     { | 
 | 900 |         return "/redfish/v1/Managers/bmc/LogServices/Dump/Entries/"; | 
 | 901 |     } | 
 | 902 |     if (dumpPath == "/xyz/openbmc_project/dump/system/entry") | 
 | 903 |     { | 
 | 904 |         return "/redfish/v1/Systems/system/LogServices/Dump/Entries/"; | 
 | 905 |     } | 
 | 906 |     return ""; | 
 | 907 | } | 
 | 908 |  | 
 | 909 | inline void createDumpTaskCallback( | 
 | 910 |     task::Payload&& payload, | 
 | 911 |     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 912 |     const sdbusplus::message::object_path& createdObjPath) | 
 | 913 | { | 
 | 914 |     const std::string dumpPath = createdObjPath.parent_path().str; | 
 | 915 |     const std::string dumpId = createdObjPath.filename(); | 
 | 916 |  | 
 | 917 |     std::string dumpEntryPath = getDumpEntryPath(dumpPath); | 
 | 918 |  | 
 | 919 |     if (dumpEntryPath.empty()) | 
 | 920 |     { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 921 |         BMCWEB_LOG_ERROR("Invalid dump type received"); | 
| Asmitha Karunanithi | 8e31778 | 2020-12-10 03:35:05 -0600 | [diff] [blame] | 922 |         messages::internalError(asyncResp->res); | 
 | 923 |         return; | 
 | 924 |     } | 
 | 925 |  | 
 | 926 |     crow::connections::systemBus->async_method_call( | 
 | 927 |         [asyncResp, payload, createdObjPath, | 
 | 928 |          dumpEntryPath{std::move(dumpEntryPath)}, | 
| Ed Tanous | 5e7e2dc | 2023-02-16 10:37:01 -0800 | [diff] [blame] | 929 |          dumpId](const boost::system::error_code& ec, | 
| Asmitha Karunanithi | 8e31778 | 2020-12-10 03:35:05 -0600 | [diff] [blame] | 930 |                  const std::string& introspectXml) { | 
 | 931 |         if (ec) | 
 | 932 |         { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 933 |             BMCWEB_LOG_ERROR("Introspect call failed with error: {}", | 
 | 934 |                              ec.message()); | 
| Asmitha Karunanithi | 8e31778 | 2020-12-10 03:35:05 -0600 | [diff] [blame] | 935 |             messages::internalError(asyncResp->res); | 
 | 936 |             return; | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 937 |         } | 
 | 938 |  | 
| Asmitha Karunanithi | 8e31778 | 2020-12-10 03:35:05 -0600 | [diff] [blame] | 939 |         // Check if the created dump object has implemented Progress | 
 | 940 |         // interface to track dump completion. If yes, fetch the "Status" | 
 | 941 |         // property of the interface, modify the task state accordingly. | 
 | 942 |         // Else, return task completed. | 
 | 943 |         tinyxml2::XMLDocument doc; | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 944 |  | 
| Asmitha Karunanithi | 8e31778 | 2020-12-10 03:35:05 -0600 | [diff] [blame] | 945 |         doc.Parse(introspectXml.data(), introspectXml.size()); | 
 | 946 |         tinyxml2::XMLNode* pRoot = doc.FirstChildElement("node"); | 
 | 947 |         if (pRoot == nullptr) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 948 |         { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 949 |             BMCWEB_LOG_ERROR("XML document failed to parse"); | 
| Asmitha Karunanithi | 8e31778 | 2020-12-10 03:35:05 -0600 | [diff] [blame] | 950 |             messages::internalError(asyncResp->res); | 
 | 951 |             return; | 
 | 952 |         } | 
 | 953 |         tinyxml2::XMLElement* interfaceNode = | 
 | 954 |             pRoot->FirstChildElement("interface"); | 
 | 955 |  | 
 | 956 |         bool isProgressIntfPresent = false; | 
 | 957 |         while (interfaceNode != nullptr) | 
 | 958 |         { | 
 | 959 |             const char* thisInterfaceName = interfaceNode->Attribute("name"); | 
 | 960 |             if (thisInterfaceName != nullptr) | 
 | 961 |             { | 
 | 962 |                 if (thisInterfaceName == | 
 | 963 |                     std::string_view("xyz.openbmc_project.Common.Progress")) | 
 | 964 |                 { | 
 | 965 |                     interfaceNode = | 
 | 966 |                         interfaceNode->NextSiblingElement("interface"); | 
 | 967 |                     continue; | 
 | 968 |                 } | 
 | 969 |                 isProgressIntfPresent = true; | 
 | 970 |                 break; | 
 | 971 |             } | 
 | 972 |             interfaceNode = interfaceNode->NextSiblingElement("interface"); | 
 | 973 |         } | 
 | 974 |  | 
 | 975 |         std::shared_ptr<task::TaskData> task = task::TaskData::createTask( | 
 | 976 |             [createdObjPath, dumpEntryPath, dumpId, isProgressIntfPresent]( | 
| Ed Tanous | 8b24275 | 2023-06-27 17:17:13 -0700 | [diff] [blame] | 977 |                 const boost::system::error_code& ec2, sdbusplus::message_t& msg, | 
| Asmitha Karunanithi | 8e31778 | 2020-12-10 03:35:05 -0600 | [diff] [blame] | 978 |                 const std::shared_ptr<task::TaskData>& taskData) { | 
| Ed Tanous | 8b24275 | 2023-06-27 17:17:13 -0700 | [diff] [blame] | 979 |             if (ec2) | 
| Asmitha Karunanithi | 8e31778 | 2020-12-10 03:35:05 -0600 | [diff] [blame] | 980 |             { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 981 |                 BMCWEB_LOG_ERROR("{}: Error in creating dump", | 
 | 982 |                                  createdObjPath.str); | 
| Asmitha Karunanithi | 8e31778 | 2020-12-10 03:35:05 -0600 | [diff] [blame] | 983 |                 taskData->messages.emplace_back(messages::internalError()); | 
 | 984 |                 taskData->state = "Cancelled"; | 
 | 985 |                 return task::completed; | 
 | 986 |             } | 
 | 987 |  | 
 | 988 |             if (isProgressIntfPresent) | 
 | 989 |             { | 
 | 990 |                 dbus::utility::DBusPropertiesMap values; | 
 | 991 |                 std::string prop; | 
 | 992 |                 msg.read(prop, values); | 
 | 993 |  | 
 | 994 |                 DumpCreationProgress dumpStatus = | 
 | 995 |                     getDumpCompletionStatus(values); | 
 | 996 |                 if (dumpStatus == DumpCreationProgress::DUMP_CREATE_FAILED) | 
 | 997 |                 { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 998 |                     BMCWEB_LOG_ERROR("{}: Error in creating dump", | 
 | 999 |                                      createdObjPath.str); | 
| Asmitha Karunanithi | 8e31778 | 2020-12-10 03:35:05 -0600 | [diff] [blame] | 1000 |                     taskData->state = "Cancelled"; | 
 | 1001 |                     return task::completed; | 
 | 1002 |                 } | 
 | 1003 |  | 
 | 1004 |                 if (dumpStatus == DumpCreationProgress::DUMP_CREATE_INPROGRESS) | 
 | 1005 |                 { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1006 |                     BMCWEB_LOG_DEBUG("{}: Dump creation task is in progress", | 
 | 1007 |                                      createdObjPath.str); | 
| Asmitha Karunanithi | 8e31778 | 2020-12-10 03:35:05 -0600 | [diff] [blame] | 1008 |                     return !task::completed; | 
 | 1009 |                 } | 
 | 1010 |             } | 
 | 1011 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1012 |             nlohmann::json retMessage = messages::success(); | 
 | 1013 |             taskData->messages.emplace_back(retMessage); | 
 | 1014 |  | 
| Ed Tanous | c51a58e | 2023-03-27 14:43:19 -0700 | [diff] [blame] | 1015 |             boost::urls::url url = boost::urls::format( | 
 | 1016 |                 "/redfish/v1/Managers/bmc/LogServices/Dump/Entries/{}", dumpId); | 
 | 1017 |  | 
 | 1018 |             std::string headerLoc = "Location: "; | 
 | 1019 |             headerLoc += url.buffer(); | 
 | 1020 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1021 |             taskData->payload->httpHeaders.emplace_back(std::move(headerLoc)); | 
 | 1022 |  | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1023 |             BMCWEB_LOG_DEBUG("{}: Dump creation task completed", | 
 | 1024 |                              createdObjPath.str); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1025 |             taskData->state = "Completed"; | 
 | 1026 |             return task::completed; | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 1027 |         }, | 
| Asmitha Karunanithi | 8e31778 | 2020-12-10 03:35:05 -0600 | [diff] [blame] | 1028 |             "type='signal',interface='org.freedesktop.DBus.Properties'," | 
 | 1029 |             "member='PropertiesChanged',path='" + | 
 | 1030 |                 createdObjPath.str + "'"); | 
| Asmitha Karunanithi | a43be80 | 2020-05-07 05:05:36 -0500 | [diff] [blame] | 1031 |  | 
| Asmitha Karunanithi | 8e31778 | 2020-12-10 03:35:05 -0600 | [diff] [blame] | 1032 |         // The task timer is set to max time limit within which the | 
 | 1033 |         // requested dump will be collected. | 
 | 1034 |         task->startTimer(std::chrono::minutes(6)); | 
 | 1035 |         task->populateResp(asyncResp->res); | 
 | 1036 |         task->payload.emplace(payload); | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 1037 |     }, | 
| Asmitha Karunanithi | 8e31778 | 2020-12-10 03:35:05 -0600 | [diff] [blame] | 1038 |         "xyz.openbmc_project.Dump.Manager", createdObjPath, | 
 | 1039 |         "org.freedesktop.DBus.Introspectable", "Introspect"); | 
| Asmitha Karunanithi | a43be80 | 2020-05-07 05:05:36 -0500 | [diff] [blame] | 1040 | } | 
 | 1041 |  | 
| zhanghch05 | 8d1b46d | 2021-04-01 11:18:24 +0800 | [diff] [blame] | 1042 | inline void createDump(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 1043 |                        const crow::Request& req, const std::string& dumpType) | 
| Asmitha Karunanithi | a43be80 | 2020-05-07 05:05:36 -0500 | [diff] [blame] | 1044 | { | 
| Claire Weinan | fdd2690 | 2022-03-01 14:18:25 -0800 | [diff] [blame] | 1045 |     std::string dumpPath = getDumpEntriesPath(dumpType); | 
 | 1046 |     if (dumpPath.empty()) | 
| Asmitha Karunanithi | a43be80 | 2020-05-07 05:05:36 -0500 | [diff] [blame] | 1047 |     { | 
| Asmitha Karunanithi | a43be80 | 2020-05-07 05:05:36 -0500 | [diff] [blame] | 1048 |         messages::internalError(asyncResp->res); | 
 | 1049 |         return; | 
 | 1050 |     } | 
 | 1051 |  | 
 | 1052 |     std::optional<std::string> diagnosticDataType; | 
 | 1053 |     std::optional<std::string> oemDiagnosticDataType; | 
 | 1054 |  | 
| Willy Tu | 15ed678 | 2021-12-14 11:03:16 -0800 | [diff] [blame] | 1055 |     if (!redfish::json_util::readJsonAction( | 
| Asmitha Karunanithi | a43be80 | 2020-05-07 05:05:36 -0500 | [diff] [blame] | 1056 |             req, asyncResp->res, "DiagnosticDataType", diagnosticDataType, | 
 | 1057 |             "OEMDiagnosticDataType", oemDiagnosticDataType)) | 
 | 1058 |     { | 
 | 1059 |         return; | 
 | 1060 |     } | 
 | 1061 |  | 
 | 1062 |     if (dumpType == "System") | 
 | 1063 |     { | 
 | 1064 |         if (!oemDiagnosticDataType || !diagnosticDataType) | 
 | 1065 |         { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1066 |             BMCWEB_LOG_ERROR( | 
 | 1067 |                 "CreateDump action parameter 'DiagnosticDataType'/'OEMDiagnosticDataType' value not found!"); | 
| Asmitha Karunanithi | a43be80 | 2020-05-07 05:05:36 -0500 | [diff] [blame] | 1068 |             messages::actionParameterMissing( | 
 | 1069 |                 asyncResp->res, "CollectDiagnosticData", | 
 | 1070 |                 "DiagnosticDataType & OEMDiagnosticDataType"); | 
 | 1071 |             return; | 
 | 1072 |         } | 
| Ed Tanous | 3174e4d | 2020-10-07 11:41:22 -0700 | [diff] [blame] | 1073 |         if ((*oemDiagnosticDataType != "System") || | 
 | 1074 |             (*diagnosticDataType != "OEM")) | 
| Asmitha Karunanithi | a43be80 | 2020-05-07 05:05:36 -0500 | [diff] [blame] | 1075 |         { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1076 |             BMCWEB_LOG_ERROR("Wrong parameter values passed"); | 
| Ed Tanous | ace85d6 | 2021-10-26 12:45:59 -0700 | [diff] [blame] | 1077 |             messages::internalError(asyncResp->res); | 
| Asmitha Karunanithi | a43be80 | 2020-05-07 05:05:36 -0500 | [diff] [blame] | 1078 |             return; | 
 | 1079 |         } | 
| Asmitha Karunanithi | 5907571 | 2021-10-22 01:17:41 -0500 | [diff] [blame] | 1080 |         dumpPath = "/redfish/v1/Systems/system/LogServices/Dump/"; | 
| Asmitha Karunanithi | a43be80 | 2020-05-07 05:05:36 -0500 | [diff] [blame] | 1081 |     } | 
 | 1082 |     else if (dumpType == "BMC") | 
 | 1083 |     { | 
 | 1084 |         if (!diagnosticDataType) | 
 | 1085 |         { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1086 |             BMCWEB_LOG_ERROR( | 
 | 1087 |                 "CreateDump action parameter 'DiagnosticDataType' not found!"); | 
| Asmitha Karunanithi | a43be80 | 2020-05-07 05:05:36 -0500 | [diff] [blame] | 1088 |             messages::actionParameterMissing( | 
 | 1089 |                 asyncResp->res, "CollectDiagnosticData", "DiagnosticDataType"); | 
 | 1090 |             return; | 
 | 1091 |         } | 
| Ed Tanous | 3174e4d | 2020-10-07 11:41:22 -0700 | [diff] [blame] | 1092 |         if (*diagnosticDataType != "Manager") | 
| Asmitha Karunanithi | a43be80 | 2020-05-07 05:05:36 -0500 | [diff] [blame] | 1093 |         { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1094 |             BMCWEB_LOG_ERROR( | 
 | 1095 |                 "Wrong parameter value passed for 'DiagnosticDataType'"); | 
| Ed Tanous | ace85d6 | 2021-10-26 12:45:59 -0700 | [diff] [blame] | 1096 |             messages::internalError(asyncResp->res); | 
| Asmitha Karunanithi | a43be80 | 2020-05-07 05:05:36 -0500 | [diff] [blame] | 1097 |             return; | 
 | 1098 |         } | 
| Asmitha Karunanithi | 5907571 | 2021-10-22 01:17:41 -0500 | [diff] [blame] | 1099 |         dumpPath = "/redfish/v1/Managers/bmc/LogServices/Dump/"; | 
 | 1100 |     } | 
 | 1101 |     else | 
 | 1102 |     { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1103 |         BMCWEB_LOG_ERROR("CreateDump failed. Unknown dump type"); | 
| Asmitha Karunanithi | 5907571 | 2021-10-22 01:17:41 -0500 | [diff] [blame] | 1104 |         messages::internalError(asyncResp->res); | 
 | 1105 |         return; | 
| Asmitha Karunanithi | a43be80 | 2020-05-07 05:05:36 -0500 | [diff] [blame] | 1106 |     } | 
 | 1107 |  | 
| Asmitha Karunanithi | 8e31778 | 2020-12-10 03:35:05 -0600 | [diff] [blame] | 1108 |     std::vector<std::pair<std::string, std::variant<std::string, uint64_t>>> | 
 | 1109 |         createDumpParamVec; | 
 | 1110 |  | 
| Carson Labrado | f574a8e | 2023-03-22 02:26:00 +0000 | [diff] [blame] | 1111 |     if (req.session != nullptr) | 
 | 1112 |     { | 
 | 1113 |         createDumpParamVec.emplace_back( | 
 | 1114 |             "xyz.openbmc_project.Dump.Create.CreateParameters.OriginatorId", | 
 | 1115 |             req.session->clientIp); | 
 | 1116 |         createDumpParamVec.emplace_back( | 
 | 1117 |             "xyz.openbmc_project.Dump.Create.CreateParameters.OriginatorType", | 
 | 1118 |             "xyz.openbmc_project.Common.OriginatedBy.OriginatorTypes.Client"); | 
 | 1119 |     } | 
| Asmitha Karunanithi | 68dd075 | 2022-11-15 11:33:46 -0600 | [diff] [blame] | 1120 |  | 
| Asmitha Karunanithi | a43be80 | 2020-05-07 05:05:36 -0500 | [diff] [blame] | 1121 |     crow::connections::systemBus->async_method_call( | 
| Ed Tanous | 5e7e2dc | 2023-02-16 10:37:01 -0800 | [diff] [blame] | 1122 |         [asyncResp, payload(task::Payload(req)), | 
 | 1123 |          dumpPath](const boost::system::error_code& ec, | 
 | 1124 |                    const sdbusplus::message_t& msg, | 
 | 1125 |                    const sdbusplus::message::object_path& objPath) mutable { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1126 |         if (ec) | 
 | 1127 |         { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1128 |             BMCWEB_LOG_ERROR("CreateDump resp_handler got error {}", ec); | 
| Asmitha Karunanithi | 5907571 | 2021-10-22 01:17:41 -0500 | [diff] [blame] | 1129 |             const sd_bus_error* dbusError = msg.get_error(); | 
 | 1130 |             if (dbusError == nullptr) | 
 | 1131 |             { | 
 | 1132 |                 messages::internalError(asyncResp->res); | 
 | 1133 |                 return; | 
 | 1134 |             } | 
 | 1135 |  | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1136 |             BMCWEB_LOG_ERROR("CreateDump DBus error: {} and error msg: {}", | 
 | 1137 |                              dbusError->name, dbusError->message); | 
| Asmitha Karunanithi | 5907571 | 2021-10-22 01:17:41 -0500 | [diff] [blame] | 1138 |             if (std::string_view( | 
 | 1139 |                     "xyz.openbmc_project.Common.Error.NotAllowed") == | 
 | 1140 |                 dbusError->name) | 
 | 1141 |             { | 
 | 1142 |                 messages::resourceInStandby(asyncResp->res); | 
 | 1143 |                 return; | 
 | 1144 |             } | 
 | 1145 |             if (std::string_view( | 
 | 1146 |                     "xyz.openbmc_project.Dump.Create.Error.Disabled") == | 
 | 1147 |                 dbusError->name) | 
 | 1148 |             { | 
 | 1149 |                 messages::serviceDisabled(asyncResp->res, dumpPath); | 
 | 1150 |                 return; | 
 | 1151 |             } | 
 | 1152 |             if (std::string_view( | 
 | 1153 |                     "xyz.openbmc_project.Common.Error.Unavailable") == | 
 | 1154 |                 dbusError->name) | 
 | 1155 |             { | 
 | 1156 |                 messages::resourceInUse(asyncResp->res); | 
 | 1157 |                 return; | 
 | 1158 |             } | 
 | 1159 |             // Other Dbus errors such as: | 
 | 1160 |             // xyz.openbmc_project.Common.Error.InvalidArgument & | 
 | 1161 |             // org.freedesktop.DBus.Error.InvalidArgs are all related to | 
 | 1162 |             // the dbus call that is made here in the bmcweb | 
 | 1163 |             // implementation and has nothing to do with the client's | 
 | 1164 |             // input in the request. Hence, returning internal error | 
 | 1165 |             // back to the client. | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1166 |             messages::internalError(asyncResp->res); | 
 | 1167 |             return; | 
 | 1168 |         } | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1169 |         BMCWEB_LOG_DEBUG("Dump Created. Path: {}", objPath.str); | 
| Asmitha Karunanithi | 8e31778 | 2020-12-10 03:35:05 -0600 | [diff] [blame] | 1170 |         createDumpTaskCallback(std::move(payload), asyncResp, objPath); | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 1171 |     }, | 
| Asmitha Karunanithi | b47452b | 2020-09-25 02:02:19 -0500 | [diff] [blame] | 1172 |         "xyz.openbmc_project.Dump.Manager", | 
 | 1173 |         "/xyz/openbmc_project/dump/" + | 
 | 1174 |             std::string(boost::algorithm::to_lower_copy(dumpType)), | 
| Asmitha Karunanithi | 8e31778 | 2020-12-10 03:35:05 -0600 | [diff] [blame] | 1175 |         "xyz.openbmc_project.Dump.Create", "CreateDump", createDumpParamVec); | 
| Asmitha Karunanithi | a43be80 | 2020-05-07 05:05:36 -0500 | [diff] [blame] | 1176 | } | 
 | 1177 |  | 
| zhanghch05 | 8d1b46d | 2021-04-01 11:18:24 +0800 | [diff] [blame] | 1178 | inline void clearDump(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 1179 |                       const std::string& dumpType) | 
| Asmitha Karunanithi | 80319af | 2020-05-07 05:30:21 -0500 | [diff] [blame] | 1180 | { | 
| Asmitha Karunanithi | b47452b | 2020-09-25 02:02:19 -0500 | [diff] [blame] | 1181 |     std::string dumpTypeLowerCopy = | 
 | 1182 |         std::string(boost::algorithm::to_lower_copy(dumpType)); | 
| zhanghch05 | 8d1b46d | 2021-04-01 11:18:24 +0800 | [diff] [blame] | 1183 |  | 
| Claire Weinan | 0d94621 | 2022-07-13 19:40:19 -0700 | [diff] [blame] | 1184 |     crow::connections::systemBus->async_method_call( | 
 | 1185 |         [asyncResp](const boost::system::error_code& ec) { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1186 |         if (ec) | 
 | 1187 |         { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1188 |             BMCWEB_LOG_ERROR("clearDump resp_handler got error {}", ec); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1189 |             messages::internalError(asyncResp->res); | 
 | 1190 |             return; | 
 | 1191 |         } | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 1192 |     }, | 
| Claire Weinan | 0d94621 | 2022-07-13 19:40:19 -0700 | [diff] [blame] | 1193 |         "xyz.openbmc_project.Dump.Manager", | 
 | 1194 |         "/xyz/openbmc_project/dump/" + dumpTypeLowerCopy, | 
 | 1195 |         "xyz.openbmc_project.Collection.DeleteAll", "DeleteAll"); | 
| Asmitha Karunanithi | 80319af | 2020-05-07 05:30:21 -0500 | [diff] [blame] | 1196 | } | 
 | 1197 |  | 
| Ed Tanous | b9d36b4 | 2022-02-26 21:42:46 -0800 | [diff] [blame] | 1198 | inline static void | 
 | 1199 |     parseCrashdumpParameters(const dbus::utility::DBusPropertiesMap& params, | 
 | 1200 |                              std::string& filename, std::string& timestamp, | 
 | 1201 |                              std::string& logfile) | 
| Johnathan Mantey | 043a053 | 2020-03-10 17:15:28 -0700 | [diff] [blame] | 1202 | { | 
| Krzysztof Grobelny | d1bde9e | 2022-09-07 10:40:51 +0200 | [diff] [blame] | 1203 |     const std::string* filenamePtr = nullptr; | 
 | 1204 |     const std::string* timestampPtr = nullptr; | 
 | 1205 |     const std::string* logfilePtr = nullptr; | 
 | 1206 |  | 
 | 1207 |     const bool success = sdbusplus::unpackPropertiesNoThrow( | 
 | 1208 |         dbus_utils::UnpackErrorPrinter(), params, "Timestamp", timestampPtr, | 
 | 1209 |         "Filename", filenamePtr, "Log", logfilePtr); | 
 | 1210 |  | 
 | 1211 |     if (!success) | 
| Johnathan Mantey | 043a053 | 2020-03-10 17:15:28 -0700 | [diff] [blame] | 1212 |     { | 
| Krzysztof Grobelny | d1bde9e | 2022-09-07 10:40:51 +0200 | [diff] [blame] | 1213 |         return; | 
 | 1214 |     } | 
 | 1215 |  | 
 | 1216 |     if (filenamePtr != nullptr) | 
 | 1217 |     { | 
 | 1218 |         filename = *filenamePtr; | 
 | 1219 |     } | 
 | 1220 |  | 
 | 1221 |     if (timestampPtr != nullptr) | 
 | 1222 |     { | 
 | 1223 |         timestamp = *timestampPtr; | 
 | 1224 |     } | 
 | 1225 |  | 
 | 1226 |     if (logfilePtr != nullptr) | 
 | 1227 |     { | 
 | 1228 |         logfile = *logfilePtr; | 
| Johnathan Mantey | 043a053 | 2020-03-10 17:15:28 -0700 | [diff] [blame] | 1229 |     } | 
 | 1230 | } | 
 | 1231 |  | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 1232 | inline void requestRoutesSystemLogServiceCollection(App& app) | 
| Ed Tanous | 1da66f7 | 2018-07-27 16:13:37 -0700 | [diff] [blame] | 1233 | { | 
| Jason M. Bills | c4bf637 | 2018-11-05 13:48:27 -0800 | [diff] [blame] | 1234 |     /** | 
 | 1235 |      * Functions triggers appropriate requests on DBus | 
 | 1236 |      */ | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 1237 |     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/") | 
| Ed Tanous | ed39821 | 2021-06-09 17:05:54 -0700 | [diff] [blame] | 1238 |         .privileges(redfish::privileges::getLogServiceCollection) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1239 |         .methods(boost::beast::http::verb::get)( | 
 | 1240 |             [&app](const crow::Request& req, | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 1241 |                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 1242 |                    const std::string& systemName) { | 
| Carson Labrado | 3ba0007 | 2022-06-06 19:40:56 +0000 | [diff] [blame] | 1243 |         if (!redfish::setUpRedfishRoute(app, req, asyncResp)) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1244 |         { | 
 | 1245 |             return; | 
 | 1246 |         } | 
| Ed Tanous | 7f3e84a | 2022-12-28 16:22:54 -0800 | [diff] [blame] | 1247 |         if constexpr (bmcwebEnableMultiHost) | 
 | 1248 |         { | 
 | 1249 |             // Option currently returns no systems.  TBD | 
 | 1250 |             messages::resourceNotFound(asyncResp->res, "ComputerSystem", | 
 | 1251 |                                        systemName); | 
 | 1252 |             return; | 
 | 1253 |         } | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 1254 |         if (systemName != "system") | 
 | 1255 |         { | 
 | 1256 |             messages::resourceNotFound(asyncResp->res, "ComputerSystem", | 
 | 1257 |                                        systemName); | 
 | 1258 |             return; | 
 | 1259 |         } | 
 | 1260 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1261 |         // Collections don't include the static data added by SubRoute | 
 | 1262 |         // because it has a duplicate entry for members | 
 | 1263 |         asyncResp->res.jsonValue["@odata.type"] = | 
 | 1264 |             "#LogServiceCollection.LogServiceCollection"; | 
 | 1265 |         asyncResp->res.jsonValue["@odata.id"] = | 
 | 1266 |             "/redfish/v1/Systems/system/LogServices"; | 
 | 1267 |         asyncResp->res.jsonValue["Name"] = "System Log Services Collection"; | 
 | 1268 |         asyncResp->res.jsonValue["Description"] = | 
 | 1269 |             "Collection of LogServices for this Computer System"; | 
 | 1270 |         nlohmann::json& logServiceArray = asyncResp->res.jsonValue["Members"]; | 
 | 1271 |         logServiceArray = nlohmann::json::array(); | 
 | 1272 |         nlohmann::json::object_t eventLog; | 
 | 1273 |         eventLog["@odata.id"] = | 
 | 1274 |             "/redfish/v1/Systems/system/LogServices/EventLog"; | 
| Patrick Williams | b2ba307 | 2023-05-12 10:27:39 -0500 | [diff] [blame] | 1275 |         logServiceArray.emplace_back(std::move(eventLog)); | 
| Asmitha Karunanithi | 5cb1dd2 | 2020-05-07 04:35:02 -0500 | [diff] [blame] | 1276 | #ifdef BMCWEB_ENABLE_REDFISH_DUMP_LOG | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1277 |         nlohmann::json::object_t dumpLog; | 
 | 1278 |         dumpLog["@odata.id"] = "/redfish/v1/Systems/system/LogServices/Dump"; | 
| Patrick Williams | b2ba307 | 2023-05-12 10:27:39 -0500 | [diff] [blame] | 1279 |         logServiceArray.emplace_back(std::move(dumpLog)); | 
| raviteja-b | c9bb686 | 2020-02-03 11:53:32 -0600 | [diff] [blame] | 1280 | #endif | 
 | 1281 |  | 
| Jason M. Bills | d53dd41 | 2019-02-12 17:16:22 -0800 | [diff] [blame] | 1282 | #ifdef BMCWEB_ENABLE_REDFISH_CPU_LOG | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1283 |         nlohmann::json::object_t crashdump; | 
 | 1284 |         crashdump["@odata.id"] = | 
 | 1285 |             "/redfish/v1/Systems/system/LogServices/Crashdump"; | 
| Patrick Williams | b2ba307 | 2023-05-12 10:27:39 -0500 | [diff] [blame] | 1286 |         logServiceArray.emplace_back(std::move(crashdump)); | 
| Jason M. Bills | d53dd41 | 2019-02-12 17:16:22 -0800 | [diff] [blame] | 1287 | #endif | 
| Spencer Ku | b7028eb | 2021-10-26 15:27:35 +0800 | [diff] [blame] | 1288 |  | 
 | 1289 | #ifdef BMCWEB_ENABLE_REDFISH_HOST_LOGGER | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1290 |         nlohmann::json::object_t hostlogger; | 
 | 1291 |         hostlogger["@odata.id"] = | 
 | 1292 |             "/redfish/v1/Systems/system/LogServices/HostLogger"; | 
| Patrick Williams | b2ba307 | 2023-05-12 10:27:39 -0500 | [diff] [blame] | 1293 |         logServiceArray.emplace_back(std::move(hostlogger)); | 
| Spencer Ku | b7028eb | 2021-10-26 15:27:35 +0800 | [diff] [blame] | 1294 | #endif | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1295 |         asyncResp->res.jsonValue["Members@odata.count"] = | 
 | 1296 |             logServiceArray.size(); | 
| ZhikuiRen | a3316fc | 2020-01-29 14:58:08 -0800 | [diff] [blame] | 1297 |  | 
| George Liu | 7a1dbc4 | 2022-12-07 16:03:22 +0800 | [diff] [blame] | 1298 |         constexpr std::array<std::string_view, 1> interfaces = { | 
 | 1299 |             "xyz.openbmc_project.State.Boot.PostCode"}; | 
 | 1300 |         dbus::utility::getSubTreePaths( | 
 | 1301 |             "/", 0, interfaces, | 
 | 1302 |             [asyncResp](const boost::system::error_code& ec, | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1303 |                         const dbus::utility::MapperGetSubTreePathsResponse& | 
 | 1304 |                             subtreePath) { | 
 | 1305 |             if (ec) | 
 | 1306 |             { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1307 |                 BMCWEB_LOG_ERROR("{}", ec); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1308 |                 return; | 
 | 1309 |             } | 
| Ed Tanous | 45ca1b8 | 2022-03-25 13:07:27 -0700 | [diff] [blame] | 1310 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1311 |             for (const auto& pathStr : subtreePath) | 
 | 1312 |             { | 
 | 1313 |                 if (pathStr.find("PostCode") != std::string::npos) | 
 | 1314 |                 { | 
 | 1315 |                     nlohmann::json& logServiceArrayLocal = | 
 | 1316 |                         asyncResp->res.jsonValue["Members"]; | 
| Ed Tanous | 613dabe | 2022-07-09 11:17:36 -0700 | [diff] [blame] | 1317 |                     nlohmann::json::object_t member; | 
 | 1318 |                     member["@odata.id"] = | 
 | 1319 |                         "/redfish/v1/Systems/system/LogServices/PostCodes"; | 
 | 1320 |  | 
| Patrick Williams | b2ba307 | 2023-05-12 10:27:39 -0500 | [diff] [blame] | 1321 |                     logServiceArrayLocal.emplace_back(std::move(member)); | 
| Ed Tanous | 613dabe | 2022-07-09 11:17:36 -0700 | [diff] [blame] | 1322 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1323 |                     asyncResp->res.jsonValue["Members@odata.count"] = | 
 | 1324 |                         logServiceArrayLocal.size(); | 
 | 1325 |                     return; | 
 | 1326 |                 } | 
 | 1327 |             } | 
| Ed Tanous | 45ca1b8 | 2022-03-25 13:07:27 -0700 | [diff] [blame] | 1328 |         }); | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 1329 |     }); | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 1330 | } | 
 | 1331 |  | 
 | 1332 | inline void requestRoutesEventLogService(App& app) | 
 | 1333 | { | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 1334 |     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/EventLog/") | 
| Ed Tanous | ed39821 | 2021-06-09 17:05:54 -0700 | [diff] [blame] | 1335 |         .privileges(redfish::privileges::getLogService) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1336 |         .methods(boost::beast::http::verb::get)( | 
 | 1337 |             [&app](const crow::Request& req, | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 1338 |                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 1339 |                    const std::string& systemName) { | 
| Carson Labrado | 3ba0007 | 2022-06-06 19:40:56 +0000 | [diff] [blame] | 1340 |         if (!redfish::setUpRedfishRoute(app, req, asyncResp)) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1341 |         { | 
 | 1342 |             return; | 
 | 1343 |         } | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 1344 |         if (systemName != "system") | 
 | 1345 |         { | 
 | 1346 |             messages::resourceNotFound(asyncResp->res, "ComputerSystem", | 
 | 1347 |                                        systemName); | 
 | 1348 |             return; | 
 | 1349 |         } | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1350 |         asyncResp->res.jsonValue["@odata.id"] = | 
 | 1351 |             "/redfish/v1/Systems/system/LogServices/EventLog"; | 
 | 1352 |         asyncResp->res.jsonValue["@odata.type"] = | 
| Janet Adkins | b25644a | 2023-08-16 11:23:45 -0500 | [diff] [blame] | 1353 |             "#LogService.v1_2_0.LogService"; | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1354 |         asyncResp->res.jsonValue["Name"] = "Event Log Service"; | 
 | 1355 |         asyncResp->res.jsonValue["Description"] = "System Event Log Service"; | 
 | 1356 |         asyncResp->res.jsonValue["Id"] = "EventLog"; | 
 | 1357 |         asyncResp->res.jsonValue["OverWritePolicy"] = "WrapsWhenFull"; | 
| Tejas Patil | 7c8c405 | 2021-06-04 17:43:14 +0530 | [diff] [blame] | 1358 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1359 |         std::pair<std::string, std::string> redfishDateTimeOffset = | 
| Ed Tanous | 2b82937 | 2022-08-03 14:22:34 -0700 | [diff] [blame] | 1360 |             redfish::time_utils::getDateTimeOffsetNow(); | 
| Tejas Patil | 7c8c405 | 2021-06-04 17:43:14 +0530 | [diff] [blame] | 1361 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1362 |         asyncResp->res.jsonValue["DateTime"] = redfishDateTimeOffset.first; | 
 | 1363 |         asyncResp->res.jsonValue["DateTimeLocalOffset"] = | 
 | 1364 |             redfishDateTimeOffset.second; | 
| Tejas Patil | 7c8c405 | 2021-06-04 17:43:14 +0530 | [diff] [blame] | 1365 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1366 |         asyncResp->res.jsonValue["Entries"]["@odata.id"] = | 
 | 1367 |             "/redfish/v1/Systems/system/LogServices/EventLog/Entries"; | 
 | 1368 |         asyncResp->res.jsonValue["Actions"]["#LogService.ClearLog"] = { | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 1369 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1370 |             {"target", | 
 | 1371 |              "/redfish/v1/Systems/system/LogServices/EventLog/Actions/LogService.ClearLog"}}; | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 1372 |     }); | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 1373 | } | 
 | 1374 |  | 
 | 1375 | inline void requestRoutesJournalEventLogClear(App& app) | 
 | 1376 | { | 
| Jason M. Bills | 4978b63 | 2022-02-22 14:17:43 -0800 | [diff] [blame] | 1377 |     BMCWEB_ROUTE( | 
 | 1378 |         app, | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 1379 |         "/redfish/v1/Systems/<str>/LogServices/EventLog/Actions/LogService.ClearLog/") | 
| Ed Tanous | 432a890 | 2021-06-14 15:28:56 -0700 | [diff] [blame] | 1380 |         .privileges({{"ConfigureComponents"}}) | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 1381 |         .methods(boost::beast::http::verb::post)( | 
| Ed Tanous | 45ca1b8 | 2022-03-25 13:07:27 -0700 | [diff] [blame] | 1382 |             [&app](const crow::Request& req, | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 1383 |                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 1384 |                    const std::string& systemName) { | 
| Carson Labrado | 3ba0007 | 2022-06-06 19:40:56 +0000 | [diff] [blame] | 1385 |         if (!redfish::setUpRedfishRoute(app, req, asyncResp)) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1386 |         { | 
 | 1387 |             return; | 
 | 1388 |         } | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 1389 |         if (systemName != "system") | 
 | 1390 |         { | 
 | 1391 |             messages::resourceNotFound(asyncResp->res, "ComputerSystem", | 
 | 1392 |                                        systemName); | 
 | 1393 |             return; | 
 | 1394 |         } | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1395 |         // Clear the EventLog by deleting the log files | 
 | 1396 |         std::vector<std::filesystem::path> redfishLogFiles; | 
 | 1397 |         if (getRedfishLogFiles(redfishLogFiles)) | 
 | 1398 |         { | 
 | 1399 |             for (const std::filesystem::path& file : redfishLogFiles) | 
 | 1400 |             { | 
 | 1401 |                 std::error_code ec; | 
 | 1402 |                 std::filesystem::remove(file, ec); | 
 | 1403 |             } | 
 | 1404 |         } | 
| Jason M. Bills | c4bf637 | 2018-11-05 13:48:27 -0800 | [diff] [blame] | 1405 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1406 |         // Reload rsyslog so it knows to start new log files | 
 | 1407 |         crow::connections::systemBus->async_method_call( | 
| Ed Tanous | 5e7e2dc | 2023-02-16 10:37:01 -0800 | [diff] [blame] | 1408 |             [asyncResp](const boost::system::error_code& ec) { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1409 |             if (ec) | 
 | 1410 |             { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1411 |                 BMCWEB_LOG_ERROR("Failed to reload rsyslog: {}", ec); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1412 |                 messages::internalError(asyncResp->res); | 
 | 1413 |                 return; | 
 | 1414 |             } | 
| Jason M. Bills | c4bf637 | 2018-11-05 13:48:27 -0800 | [diff] [blame] | 1415 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1416 |             messages::success(asyncResp->res); | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 1417 |         }, | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1418 |             "org.freedesktop.systemd1", "/org/freedesktop/systemd1", | 
 | 1419 |             "org.freedesktop.systemd1.Manager", "ReloadUnit", "rsyslog.service", | 
 | 1420 |             "replace"); | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 1421 |     }); | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 1422 | } | 
| Jason M. Bills | c4bf637 | 2018-11-05 13:48:27 -0800 | [diff] [blame] | 1423 |  | 
| Jason M. Bills | ac992cd | 2022-06-24 13:31:46 -0700 | [diff] [blame] | 1424 | enum class LogParseError | 
 | 1425 | { | 
 | 1426 |     success, | 
 | 1427 |     parseFailed, | 
 | 1428 |     messageIdNotInRegistry, | 
 | 1429 | }; | 
 | 1430 |  | 
 | 1431 | static LogParseError | 
 | 1432 |     fillEventLogEntryJson(const std::string& logEntryID, | 
 | 1433 |                           const std::string& logEntry, | 
 | 1434 |                           nlohmann::json::object_t& logEntryJson) | 
| Jason M. Bills | c4bf637 | 2018-11-05 13:48:27 -0800 | [diff] [blame] | 1435 | { | 
| Jason M. Bills | 9582018 | 2019-04-22 16:25:34 -0700 | [diff] [blame] | 1436 |     // The redfish log format is "<Timestamp> <MessageId>,<MessageArgs>" | 
| Jason M. Bills | cd225da | 2019-05-08 15:31:57 -0700 | [diff] [blame] | 1437 |     // First get the Timestamp | 
| Ed Tanous | f23b729 | 2020-10-15 09:41:17 -0700 | [diff] [blame] | 1438 |     size_t space = logEntry.find_first_of(' '); | 
| Jason M. Bills | cd225da | 2019-05-08 15:31:57 -0700 | [diff] [blame] | 1439 |     if (space == std::string::npos) | 
| Jason M. Bills | 9582018 | 2019-04-22 16:25:34 -0700 | [diff] [blame] | 1440 |     { | 
| Jason M. Bills | ac992cd | 2022-06-24 13:31:46 -0700 | [diff] [blame] | 1441 |         return LogParseError::parseFailed; | 
| Jason M. Bills | 9582018 | 2019-04-22 16:25:34 -0700 | [diff] [blame] | 1442 |     } | 
| Jason M. Bills | cd225da | 2019-05-08 15:31:57 -0700 | [diff] [blame] | 1443 |     std::string timestamp = logEntry.substr(0, space); | 
 | 1444 |     // Then get the log contents | 
| Ed Tanous | f23b729 | 2020-10-15 09:41:17 -0700 | [diff] [blame] | 1445 |     size_t entryStart = logEntry.find_first_not_of(' ', space); | 
| Jason M. Bills | cd225da | 2019-05-08 15:31:57 -0700 | [diff] [blame] | 1446 |     if (entryStart == std::string::npos) | 
 | 1447 |     { | 
| Jason M. Bills | ac992cd | 2022-06-24 13:31:46 -0700 | [diff] [blame] | 1448 |         return LogParseError::parseFailed; | 
| Jason M. Bills | cd225da | 2019-05-08 15:31:57 -0700 | [diff] [blame] | 1449 |     } | 
 | 1450 |     std::string_view entry(logEntry); | 
 | 1451 |     entry.remove_prefix(entryStart); | 
 | 1452 |     // Use split to separate the entry into its fields | 
 | 1453 |     std::vector<std::string> logEntryFields; | 
| Ed Tanous | 50ebd4a | 2023-01-19 19:03:17 -0800 | [diff] [blame] | 1454 |     bmcweb::split(logEntryFields, entry, ','); | 
| Jason M. Bills | cd225da | 2019-05-08 15:31:57 -0700 | [diff] [blame] | 1455 |     // We need at least a MessageId to be valid | 
| Ed Tanous | 1e6deaf | 2022-02-17 11:32:37 -0800 | [diff] [blame] | 1456 |     auto logEntryIter = logEntryFields.begin(); | 
 | 1457 |     if (logEntryIter == logEntryFields.end()) | 
| Jason M. Bills | cd225da | 2019-05-08 15:31:57 -0700 | [diff] [blame] | 1458 |     { | 
| Jason M. Bills | ac992cd | 2022-06-24 13:31:46 -0700 | [diff] [blame] | 1459 |         return LogParseError::parseFailed; | 
| Jason M. Bills | cd225da | 2019-05-08 15:31:57 -0700 | [diff] [blame] | 1460 |     } | 
| Ed Tanous | 1e6deaf | 2022-02-17 11:32:37 -0800 | [diff] [blame] | 1461 |     std::string& messageID = *logEntryIter; | 
| Jason M. Bills | 4851d45 | 2019-03-28 11:27:48 -0700 | [diff] [blame] | 1462 |     // Get the Message from the MessageRegistry | 
| Ed Tanous | fffb8c1 | 2022-02-07 23:53:03 -0800 | [diff] [blame] | 1463 |     const registries::Message* message = registries::getMessage(messageID); | 
| Jason M. Bills | c4bf637 | 2018-11-05 13:48:27 -0800 | [diff] [blame] | 1464 |  | 
| Ed Tanous | 1e6deaf | 2022-02-17 11:32:37 -0800 | [diff] [blame] | 1465 |     logEntryIter++; | 
| Sui Chen | 54417b0 | 2022-03-24 14:59:52 -0700 | [diff] [blame] | 1466 |     if (message == nullptr) | 
| Jason M. Bills | c4bf637 | 2018-11-05 13:48:27 -0800 | [diff] [blame] | 1467 |     { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1468 |         BMCWEB_LOG_WARNING("Log entry not found in registry: {}", logEntry); | 
| Jason M. Bills | ac992cd | 2022-06-24 13:31:46 -0700 | [diff] [blame] | 1469 |         return LogParseError::messageIdNotInRegistry; | 
| Jason M. Bills | c4bf637 | 2018-11-05 13:48:27 -0800 | [diff] [blame] | 1470 |     } | 
 | 1471 |  | 
| Ed Tanous | 1e6deaf | 2022-02-17 11:32:37 -0800 | [diff] [blame] | 1472 |     std::vector<std::string_view> messageArgs(logEntryIter, | 
 | 1473 |                                               logEntryFields.end()); | 
| Ed Tanous | c05bba4 | 2023-06-28 08:33:29 -0700 | [diff] [blame] | 1474 |     messageArgs.resize(message->numberOfArgs); | 
 | 1475 |  | 
| Ed Tanous | 1e6deaf | 2022-02-17 11:32:37 -0800 | [diff] [blame] | 1476 |     std::string msg = redfish::registries::fillMessageArgs(messageArgs, | 
 | 1477 |                                                            message->message); | 
 | 1478 |     if (msg.empty()) | 
| Jason M. Bills | 4851d45 | 2019-03-28 11:27:48 -0700 | [diff] [blame] | 1479 |     { | 
| Ed Tanous | 1e6deaf | 2022-02-17 11:32:37 -0800 | [diff] [blame] | 1480 |         return LogParseError::parseFailed; | 
| Jason M. Bills | 4851d45 | 2019-03-28 11:27:48 -0700 | [diff] [blame] | 1481 |     } | 
 | 1482 |  | 
| Jason M. Bills | 9582018 | 2019-04-22 16:25:34 -0700 | [diff] [blame] | 1483 |     // Get the Created time from the timestamp. The log timestamp is in RFC3339 | 
 | 1484 |     // format which matches the Redfish format except for the fractional seconds | 
 | 1485 |     // between the '.' and the '+', so just remove them. | 
| Ed Tanous | f23b729 | 2020-10-15 09:41:17 -0700 | [diff] [blame] | 1486 |     std::size_t dot = timestamp.find_first_of('.'); | 
 | 1487 |     std::size_t plus = timestamp.find_first_of('+'); | 
| Jason M. Bills | 9582018 | 2019-04-22 16:25:34 -0700 | [diff] [blame] | 1488 |     if (dot != std::string::npos && plus != std::string::npos) | 
| Jason M. Bills | c4bf637 | 2018-11-05 13:48:27 -0800 | [diff] [blame] | 1489 |     { | 
| Jason M. Bills | 9582018 | 2019-04-22 16:25:34 -0700 | [diff] [blame] | 1490 |         timestamp.erase(dot, plus - dot); | 
| Jason M. Bills | c4bf637 | 2018-11-05 13:48:27 -0800 | [diff] [blame] | 1491 |     } | 
 | 1492 |  | 
 | 1493 |     // Fill in the log entry with the gathered data | 
| Vijay Lobo | 9c11a17 | 2021-10-07 16:53:16 -0500 | [diff] [blame] | 1494 |     logEntryJson["@odata.type"] = "#LogEntry.v1_9_0.LogEntry"; | 
| Ed Tanous | ef4c65b | 2023-04-24 15:28:50 -0700 | [diff] [blame] | 1495 |     logEntryJson["@odata.id"] = boost::urls::format( | 
 | 1496 |         "/redfish/v1/Systems/system/LogServices/EventLog/Entries/{}", | 
 | 1497 |         logEntryID); | 
| Jason M. Bills | 84afc48 | 2022-06-24 12:38:23 -0700 | [diff] [blame] | 1498 |     logEntryJson["Name"] = "System Event Log Entry"; | 
 | 1499 |     logEntryJson["Id"] = logEntryID; | 
 | 1500 |     logEntryJson["Message"] = std::move(msg); | 
 | 1501 |     logEntryJson["MessageId"] = std::move(messageID); | 
 | 1502 |     logEntryJson["MessageArgs"] = messageArgs; | 
 | 1503 |     logEntryJson["EntryType"] = "Event"; | 
 | 1504 |     logEntryJson["Severity"] = message->messageSeverity; | 
 | 1505 |     logEntryJson["Created"] = std::move(timestamp); | 
| Jason M. Bills | ac992cd | 2022-06-24 13:31:46 -0700 | [diff] [blame] | 1506 |     return LogParseError::success; | 
| Jason M. Bills | c4bf637 | 2018-11-05 13:48:27 -0800 | [diff] [blame] | 1507 | } | 
 | 1508 |  | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 1509 | inline void requestRoutesJournalEventLogEntryCollection(App& app) | 
| Jason M. Bills | c4bf637 | 2018-11-05 13:48:27 -0800 | [diff] [blame] | 1510 | { | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 1511 |     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/") | 
| Gunnar Mills | 8b6a35f | 2021-07-30 14:52:53 -0500 | [diff] [blame] | 1512 |         .privileges(redfish::privileges::getLogEntryCollection) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1513 |         .methods(boost::beast::http::verb::get)( | 
 | 1514 |             [&app](const crow::Request& req, | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 1515 |                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 1516 |                    const std::string& systemName) { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1517 |         query_param::QueryCapabilities capabilities = { | 
 | 1518 |             .canDelegateTop = true, | 
 | 1519 |             .canDelegateSkip = true, | 
 | 1520 |         }; | 
 | 1521 |         query_param::Query delegatedQuery; | 
 | 1522 |         if (!redfish::setUpRedfishRouteWithDelegation( | 
| Carson Labrado | 3ba0007 | 2022-06-06 19:40:56 +0000 | [diff] [blame] | 1523 |                 app, req, asyncResp, delegatedQuery, capabilities)) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1524 |         { | 
 | 1525 |             return; | 
 | 1526 |         } | 
| Ed Tanous | 7f3e84a | 2022-12-28 16:22:54 -0800 | [diff] [blame] | 1527 |         if constexpr (bmcwebEnableMultiHost) | 
 | 1528 |         { | 
 | 1529 |             // Option currently returns no systems.  TBD | 
 | 1530 |             messages::resourceNotFound(asyncResp->res, "ComputerSystem", | 
 | 1531 |                                        systemName); | 
 | 1532 |             return; | 
 | 1533 |         } | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 1534 |         if (systemName != "system") | 
 | 1535 |         { | 
 | 1536 |             messages::resourceNotFound(asyncResp->res, "ComputerSystem", | 
 | 1537 |                                        systemName); | 
 | 1538 |             return; | 
 | 1539 |         } | 
 | 1540 |  | 
| Jiaqing Zhao | 5143f7a | 2022-07-22 09:33:33 +0800 | [diff] [blame] | 1541 |         size_t top = delegatedQuery.top.value_or(query_param::Query::maxTop); | 
| Ed Tanous | 3648c8b | 2022-07-25 13:39:59 -0700 | [diff] [blame] | 1542 |         size_t skip = delegatedQuery.skip.value_or(0); | 
 | 1543 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1544 |         // Collections don't include the static data added by SubRoute | 
 | 1545 |         // because it has a duplicate entry for members | 
 | 1546 |         asyncResp->res.jsonValue["@odata.type"] = | 
 | 1547 |             "#LogEntryCollection.LogEntryCollection"; | 
 | 1548 |         asyncResp->res.jsonValue["@odata.id"] = | 
 | 1549 |             "/redfish/v1/Systems/system/LogServices/EventLog/Entries"; | 
 | 1550 |         asyncResp->res.jsonValue["Name"] = "System Event Log Entries"; | 
 | 1551 |         asyncResp->res.jsonValue["Description"] = | 
 | 1552 |             "Collection of System Event Log Entries"; | 
 | 1553 |  | 
 | 1554 |         nlohmann::json& logEntryArray = asyncResp->res.jsonValue["Members"]; | 
 | 1555 |         logEntryArray = nlohmann::json::array(); | 
 | 1556 |         // Go through the log files and create a unique ID for each | 
 | 1557 |         // entry | 
 | 1558 |         std::vector<std::filesystem::path> redfishLogFiles; | 
 | 1559 |         getRedfishLogFiles(redfishLogFiles); | 
 | 1560 |         uint64_t entryCount = 0; | 
 | 1561 |         std::string logEntry; | 
 | 1562 |  | 
 | 1563 |         // Oldest logs are in the last file, so start there and loop | 
 | 1564 |         // backwards | 
 | 1565 |         for (auto it = redfishLogFiles.rbegin(); it < redfishLogFiles.rend(); | 
 | 1566 |              it++) | 
 | 1567 |         { | 
 | 1568 |             std::ifstream logStream(*it); | 
 | 1569 |             if (!logStream.is_open()) | 
| Jason M. Bills | 4978b63 | 2022-02-22 14:17:43 -0800 | [diff] [blame] | 1570 |             { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1571 |                 continue; | 
| Jason M. Bills | 4978b63 | 2022-02-22 14:17:43 -0800 | [diff] [blame] | 1572 |             } | 
| Jason M. Bills | 897967d | 2019-07-29 17:05:30 -0700 | [diff] [blame] | 1573 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1574 |             // Reset the unique ID on the first entry | 
 | 1575 |             bool firstEntry = true; | 
 | 1576 |             while (std::getline(logStream, logEntry)) | 
| Jason M. Bills | 4978b63 | 2022-02-22 14:17:43 -0800 | [diff] [blame] | 1577 |             { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1578 |                 std::string idStr; | 
 | 1579 |                 if (!getUniqueEntryID(logEntry, idStr, firstEntry)) | 
| Jason M. Bills | 4978b63 | 2022-02-22 14:17:43 -0800 | [diff] [blame] | 1580 |                 { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1581 |                     continue; | 
 | 1582 |                 } | 
| Jason M. Bills | efde4ec | 2022-06-24 08:59:52 -0700 | [diff] [blame] | 1583 |                 firstEntry = false; | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 1584 |  | 
| Jason M. Bills | de703c5 | 2022-06-23 14:19:04 -0700 | [diff] [blame] | 1585 |                 nlohmann::json::object_t bmcLogEntry; | 
| Patrick Williams | 89492a1 | 2023-05-10 07:51:34 -0500 | [diff] [blame] | 1586 |                 LogParseError status = fillEventLogEntryJson(idStr, logEntry, | 
 | 1587 |                                                              bmcLogEntry); | 
| Jason M. Bills | ac992cd | 2022-06-24 13:31:46 -0700 | [diff] [blame] | 1588 |                 if (status == LogParseError::messageIdNotInRegistry) | 
 | 1589 |                 { | 
 | 1590 |                     continue; | 
 | 1591 |                 } | 
 | 1592 |                 if (status != LogParseError::success) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1593 |                 { | 
 | 1594 |                     messages::internalError(asyncResp->res); | 
 | 1595 |                     return; | 
| Andrew Geissler | cb92c03 | 2018-08-17 07:56:14 -0700 | [diff] [blame] | 1596 |                 } | 
| Jason M. Bills | de703c5 | 2022-06-23 14:19:04 -0700 | [diff] [blame] | 1597 |  | 
| Jason M. Bills | de703c5 | 2022-06-23 14:19:04 -0700 | [diff] [blame] | 1598 |                 entryCount++; | 
 | 1599 |                 // Handle paging using skip (number of entries to skip from the | 
 | 1600 |                 // start) and top (number of entries to display) | 
| Ed Tanous | 3648c8b | 2022-07-25 13:39:59 -0700 | [diff] [blame] | 1601 |                 if (entryCount <= skip || entryCount > skip + top) | 
| Jason M. Bills | de703c5 | 2022-06-23 14:19:04 -0700 | [diff] [blame] | 1602 |                 { | 
 | 1603 |                     continue; | 
 | 1604 |                 } | 
 | 1605 |  | 
| Patrick Williams | b2ba307 | 2023-05-12 10:27:39 -0500 | [diff] [blame] | 1606 |                 logEntryArray.emplace_back(std::move(bmcLogEntry)); | 
| Jason M. Bills | 4978b63 | 2022-02-22 14:17:43 -0800 | [diff] [blame] | 1607 |             } | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1608 |         } | 
 | 1609 |         asyncResp->res.jsonValue["Members@odata.count"] = entryCount; | 
| Ed Tanous | 3648c8b | 2022-07-25 13:39:59 -0700 | [diff] [blame] | 1610 |         if (skip + top < entryCount) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1611 |         { | 
 | 1612 |             asyncResp->res.jsonValue["Members@odata.nextLink"] = | 
 | 1613 |                 "/redfish/v1/Systems/system/LogServices/EventLog/Entries?$skip=" + | 
| Ed Tanous | 3648c8b | 2022-07-25 13:39:59 -0700 | [diff] [blame] | 1614 |                 std::to_string(skip + top); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1615 |         } | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 1616 |     }); | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 1617 | } | 
| Chicago Duan | 336e96c | 2019-07-15 14:22:08 +0800 | [diff] [blame] | 1618 |  | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 1619 | inline void requestRoutesJournalEventLogEntry(App& app) | 
 | 1620 | { | 
 | 1621 |     BMCWEB_ROUTE( | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 1622 |         app, "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/<str>/") | 
| Ed Tanous | ed39821 | 2021-06-09 17:05:54 -0700 | [diff] [blame] | 1623 |         .privileges(redfish::privileges::getLogEntry) | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 1624 |         .methods(boost::beast::http::verb::get)( | 
| Ed Tanous | 45ca1b8 | 2022-03-25 13:07:27 -0700 | [diff] [blame] | 1625 |             [&app](const crow::Request& req, | 
 | 1626 |                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 1627 |                    const std::string& systemName, const std::string& param) { | 
| Carson Labrado | 3ba0007 | 2022-06-06 19:40:56 +0000 | [diff] [blame] | 1628 |         if (!redfish::setUpRedfishRoute(app, req, asyncResp)) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1629 |         { | 
 | 1630 |             return; | 
 | 1631 |         } | 
| Ed Tanous | 7f3e84a | 2022-12-28 16:22:54 -0800 | [diff] [blame] | 1632 |         if constexpr (bmcwebEnableMultiHost) | 
 | 1633 |         { | 
 | 1634 |             // Option currently returns no systems.  TBD | 
 | 1635 |             messages::resourceNotFound(asyncResp->res, "ComputerSystem", | 
 | 1636 |                                        systemName); | 
 | 1637 |             return; | 
 | 1638 |         } | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 1639 |  | 
 | 1640 |         if (systemName != "system") | 
 | 1641 |         { | 
 | 1642 |             messages::resourceNotFound(asyncResp->res, "ComputerSystem", | 
 | 1643 |                                        systemName); | 
 | 1644 |             return; | 
 | 1645 |         } | 
 | 1646 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1647 |         const std::string& targetID = param; | 
 | 1648 |  | 
 | 1649 |         // Go through the log files and check the unique ID for each | 
 | 1650 |         // entry to find the target entry | 
 | 1651 |         std::vector<std::filesystem::path> redfishLogFiles; | 
 | 1652 |         getRedfishLogFiles(redfishLogFiles); | 
 | 1653 |         std::string logEntry; | 
 | 1654 |  | 
 | 1655 |         // Oldest logs are in the last file, so start there and loop | 
 | 1656 |         // backwards | 
 | 1657 |         for (auto it = redfishLogFiles.rbegin(); it < redfishLogFiles.rend(); | 
 | 1658 |              it++) | 
 | 1659 |         { | 
 | 1660 |             std::ifstream logStream(*it); | 
 | 1661 |             if (!logStream.is_open()) | 
 | 1662 |             { | 
 | 1663 |                 continue; | 
 | 1664 |             } | 
 | 1665 |  | 
 | 1666 |             // Reset the unique ID on the first entry | 
 | 1667 |             bool firstEntry = true; | 
 | 1668 |             while (std::getline(logStream, logEntry)) | 
 | 1669 |             { | 
 | 1670 |                 std::string idStr; | 
 | 1671 |                 if (!getUniqueEntryID(logEntry, idStr, firstEntry)) | 
| Ed Tanous | 45ca1b8 | 2022-03-25 13:07:27 -0700 | [diff] [blame] | 1672 |                 { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1673 |                     continue; | 
 | 1674 |                 } | 
| Jason M. Bills | efde4ec | 2022-06-24 08:59:52 -0700 | [diff] [blame] | 1675 |                 firstEntry = false; | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1676 |  | 
 | 1677 |                 if (idStr == targetID) | 
 | 1678 |                 { | 
| Jason M. Bills | de703c5 | 2022-06-23 14:19:04 -0700 | [diff] [blame] | 1679 |                     nlohmann::json::object_t bmcLogEntry; | 
| Jason M. Bills | ac992cd | 2022-06-24 13:31:46 -0700 | [diff] [blame] | 1680 |                     LogParseError status = | 
 | 1681 |                         fillEventLogEntryJson(idStr, logEntry, bmcLogEntry); | 
 | 1682 |                     if (status != LogParseError::success) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1683 |                     { | 
 | 1684 |                         messages::internalError(asyncResp->res); | 
 | 1685 |                         return; | 
 | 1686 |                     } | 
| Jason M. Bills | d405bb5 | 2022-06-24 10:52:05 -0700 | [diff] [blame] | 1687 |                     asyncResp->res.jsonValue.update(bmcLogEntry); | 
| Ed Tanous | 45ca1b8 | 2022-03-25 13:07:27 -0700 | [diff] [blame] | 1688 |                     return; | 
 | 1689 |                 } | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1690 |             } | 
 | 1691 |         } | 
 | 1692 |         // Requested ID was not found | 
| Jiaqing Zhao | 9db4ba2 | 2022-10-09 17:24:40 +0800 | [diff] [blame] | 1693 |         messages::resourceNotFound(asyncResp->res, "LogEntry", targetID); | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 1694 |     }); | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 1695 | } | 
 | 1696 |  | 
 | 1697 | inline void requestRoutesDBusEventLogEntryCollection(App& app) | 
 | 1698 | { | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 1699 |     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/") | 
| Ed Tanous | ed39821 | 2021-06-09 17:05:54 -0700 | [diff] [blame] | 1700 |         .privileges(redfish::privileges::getLogEntryCollection) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1701 |         .methods(boost::beast::http::verb::get)( | 
 | 1702 |             [&app](const crow::Request& req, | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 1703 |                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 1704 |                    const std::string& systemName) { | 
| Carson Labrado | 3ba0007 | 2022-06-06 19:40:56 +0000 | [diff] [blame] | 1705 |         if (!redfish::setUpRedfishRoute(app, req, asyncResp)) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1706 |         { | 
 | 1707 |             return; | 
 | 1708 |         } | 
| Ed Tanous | 7f3e84a | 2022-12-28 16:22:54 -0800 | [diff] [blame] | 1709 |         if constexpr (bmcwebEnableMultiHost) | 
 | 1710 |         { | 
 | 1711 |             // Option currently returns no systems.  TBD | 
 | 1712 |             messages::resourceNotFound(asyncResp->res, "ComputerSystem", | 
 | 1713 |                                        systemName); | 
 | 1714 |             return; | 
 | 1715 |         } | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 1716 |         if (systemName != "system") | 
 | 1717 |         { | 
 | 1718 |             messages::resourceNotFound(asyncResp->res, "ComputerSystem", | 
 | 1719 |                                        systemName); | 
 | 1720 |             return; | 
 | 1721 |         } | 
 | 1722 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1723 |         // Collections don't include the static data added by SubRoute | 
 | 1724 |         // because it has a duplicate entry for members | 
 | 1725 |         asyncResp->res.jsonValue["@odata.type"] = | 
 | 1726 |             "#LogEntryCollection.LogEntryCollection"; | 
 | 1727 |         asyncResp->res.jsonValue["@odata.id"] = | 
 | 1728 |             "/redfish/v1/Systems/system/LogServices/EventLog/Entries"; | 
 | 1729 |         asyncResp->res.jsonValue["Name"] = "System Event Log Entries"; | 
 | 1730 |         asyncResp->res.jsonValue["Description"] = | 
 | 1731 |             "Collection of System Event Log Entries"; | 
 | 1732 |  | 
 | 1733 |         // DBus implementation of EventLog/Entries | 
 | 1734 |         // Make call to Logging Service to find all log entry objects | 
| George Liu | 5eb468d | 2023-06-20 17:03:24 +0800 | [diff] [blame] | 1735 |         sdbusplus::message::object_path path("/xyz/openbmc_project/logging"); | 
 | 1736 |         dbus::utility::getManagedObjects( | 
 | 1737 |             "xyz.openbmc_project.Logging", path, | 
| Ed Tanous | 5e7e2dc | 2023-02-16 10:37:01 -0800 | [diff] [blame] | 1738 |             [asyncResp](const boost::system::error_code& ec, | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1739 |                         const dbus::utility::ManagedObjectType& resp) { | 
 | 1740 |             if (ec) | 
| Ed Tanous | 45ca1b8 | 2022-03-25 13:07:27 -0700 | [diff] [blame] | 1741 |             { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1742 |                 // TODO Handle for specific error code | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1743 |                 BMCWEB_LOG_ERROR( | 
 | 1744 |                     "getLogEntriesIfaceData resp_handler got error {}", ec); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1745 |                 messages::internalError(asyncResp->res); | 
| Ed Tanous | 45ca1b8 | 2022-03-25 13:07:27 -0700 | [diff] [blame] | 1746 |                 return; | 
 | 1747 |             } | 
| Ed Tanous | 3544d2a | 2023-08-06 18:12:20 -0700 | [diff] [blame] | 1748 |             nlohmann::json::array_t entriesArray; | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1749 |             for (const auto& objectPath : resp) | 
 | 1750 |             { | 
 | 1751 |                 const uint32_t* id = nullptr; | 
 | 1752 |                 const uint64_t* timestamp = nullptr; | 
 | 1753 |                 const uint64_t* updateTimestamp = nullptr; | 
 | 1754 |                 const std::string* severity = nullptr; | 
 | 1755 |                 const std::string* message = nullptr; | 
 | 1756 |                 const std::string* filePath = nullptr; | 
| Vijay Lobo | 9c11a17 | 2021-10-07 16:53:16 -0500 | [diff] [blame] | 1757 |                 const std::string* resolution = nullptr; | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1758 |                 bool resolved = false; | 
| Abhishek Patel | 9017faf | 2021-09-14 22:48:55 -0500 | [diff] [blame] | 1759 |                 const std::string* notify = nullptr; | 
 | 1760 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1761 |                 for (const auto& interfaceMap : objectPath.second) | 
 | 1762 |                 { | 
 | 1763 |                     if (interfaceMap.first == | 
 | 1764 |                         "xyz.openbmc_project.Logging.Entry") | 
| Xiaochao Ma | 75710de | 2021-01-21 17:56:02 +0800 | [diff] [blame] | 1765 |                     { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1766 |                         for (const auto& propertyMap : interfaceMap.second) | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 1767 |                         { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1768 |                             if (propertyMap.first == "Id") | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 1769 |                             { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1770 |                                 id = std::get_if<uint32_t>(&propertyMap.second); | 
 | 1771 |                             } | 
 | 1772 |                             else if (propertyMap.first == "Timestamp") | 
 | 1773 |                             { | 
 | 1774 |                                 timestamp = | 
 | 1775 |                                     std::get_if<uint64_t>(&propertyMap.second); | 
 | 1776 |                             } | 
 | 1777 |                             else if (propertyMap.first == "UpdateTimestamp") | 
 | 1778 |                             { | 
 | 1779 |                                 updateTimestamp = | 
 | 1780 |                                     std::get_if<uint64_t>(&propertyMap.second); | 
 | 1781 |                             } | 
 | 1782 |                             else if (propertyMap.first == "Severity") | 
 | 1783 |                             { | 
 | 1784 |                                 severity = std::get_if<std::string>( | 
 | 1785 |                                     &propertyMap.second); | 
 | 1786 |                             } | 
| Vijay Lobo | 9c11a17 | 2021-10-07 16:53:16 -0500 | [diff] [blame] | 1787 |                             else if (propertyMap.first == "Resolution") | 
 | 1788 |                             { | 
 | 1789 |                                 resolution = std::get_if<std::string>( | 
 | 1790 |                                     &propertyMap.second); | 
 | 1791 |                             } | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1792 |                             else if (propertyMap.first == "Message") | 
 | 1793 |                             { | 
 | 1794 |                                 message = std::get_if<std::string>( | 
 | 1795 |                                     &propertyMap.second); | 
 | 1796 |                             } | 
 | 1797 |                             else if (propertyMap.first == "Resolved") | 
 | 1798 |                             { | 
 | 1799 |                                 const bool* resolveptr = | 
 | 1800 |                                     std::get_if<bool>(&propertyMap.second); | 
 | 1801 |                                 if (resolveptr == nullptr) | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 1802 |                                 { | 
 | 1803 |                                     messages::internalError(asyncResp->res); | 
 | 1804 |                                     return; | 
 | 1805 |                                 } | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1806 |                                 resolved = *resolveptr; | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 1807 |                             } | 
| Abhishek Patel | 9017faf | 2021-09-14 22:48:55 -0500 | [diff] [blame] | 1808 |                             else if (propertyMap.first == | 
 | 1809 |                                      "ServiceProviderNotify") | 
 | 1810 |                             { | 
 | 1811 |                                 notify = std::get_if<std::string>( | 
 | 1812 |                                     &propertyMap.second); | 
 | 1813 |                                 if (notify == nullptr) | 
 | 1814 |                                 { | 
 | 1815 |                                     messages::internalError(asyncResp->res); | 
 | 1816 |                                     return; | 
 | 1817 |                                 } | 
 | 1818 |                             } | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 1819 |                         } | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 1820 |                         if (id == nullptr || message == nullptr || | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1821 |                             severity == nullptr) | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 1822 |                         { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1823 |                             messages::internalError(asyncResp->res); | 
 | 1824 |                             return; | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 1825 |                         } | 
 | 1826 |                     } | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1827 |                     else if (interfaceMap.first == | 
 | 1828 |                              "xyz.openbmc_project.Common.FilePath") | 
 | 1829 |                     { | 
 | 1830 |                         for (const auto& propertyMap : interfaceMap.second) | 
 | 1831 |                         { | 
 | 1832 |                             if (propertyMap.first == "Path") | 
 | 1833 |                             { | 
 | 1834 |                                 filePath = std::get_if<std::string>( | 
 | 1835 |                                     &propertyMap.second); | 
 | 1836 |                             } | 
 | 1837 |                         } | 
 | 1838 |                     } | 
 | 1839 |                 } | 
 | 1840 |                 // Object path without the | 
 | 1841 |                 // xyz.openbmc_project.Logging.Entry interface, ignore | 
 | 1842 |                 // and continue. | 
 | 1843 |                 if (id == nullptr || message == nullptr || | 
 | 1844 |                     severity == nullptr || timestamp == nullptr || | 
 | 1845 |                     updateTimestamp == nullptr) | 
 | 1846 |                 { | 
 | 1847 |                     continue; | 
 | 1848 |                 } | 
| Ed Tanous | 3544d2a | 2023-08-06 18:12:20 -0700 | [diff] [blame] | 1849 |                 nlohmann::json& thisEntry = entriesArray.emplace_back(); | 
| Vijay Lobo | 9c11a17 | 2021-10-07 16:53:16 -0500 | [diff] [blame] | 1850 |                 thisEntry["@odata.type"] = "#LogEntry.v1_9_0.LogEntry"; | 
| Ed Tanous | ef4c65b | 2023-04-24 15:28:50 -0700 | [diff] [blame] | 1851 |                 thisEntry["@odata.id"] = boost::urls::format( | 
 | 1852 |                     "/redfish/v1/Systems/system/LogServices/EventLog/Entries/{}", | 
 | 1853 |                     std::to_string(*id)); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1854 |                 thisEntry["Name"] = "System Event Log Entry"; | 
 | 1855 |                 thisEntry["Id"] = std::to_string(*id); | 
 | 1856 |                 thisEntry["Message"] = *message; | 
 | 1857 |                 thisEntry["Resolved"] = resolved; | 
| Vijay Lobo | 9c11a17 | 2021-10-07 16:53:16 -0500 | [diff] [blame] | 1858 |                 if ((resolution != nullptr) && (!(*resolution).empty())) | 
 | 1859 |                 { | 
 | 1860 |                     thisEntry["Resolution"] = *resolution; | 
 | 1861 |                 } | 
| Abhishek Patel | 9017faf | 2021-09-14 22:48:55 -0500 | [diff] [blame] | 1862 |                 std::optional<bool> notifyAction = | 
 | 1863 |                     getProviderNotifyAction(*notify); | 
 | 1864 |                 if (notifyAction) | 
 | 1865 |                 { | 
 | 1866 |                     thisEntry["ServiceProviderNotified"] = *notifyAction; | 
 | 1867 |                 } | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1868 |                 thisEntry["EntryType"] = "Event"; | 
 | 1869 |                 thisEntry["Severity"] = | 
 | 1870 |                     translateSeverityDbusToRedfish(*severity); | 
 | 1871 |                 thisEntry["Created"] = | 
| Ed Tanous | 2b82937 | 2022-08-03 14:22:34 -0700 | [diff] [blame] | 1872 |                     redfish::time_utils::getDateTimeUintMs(*timestamp); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1873 |                 thisEntry["Modified"] = | 
| Ed Tanous | 2b82937 | 2022-08-03 14:22:34 -0700 | [diff] [blame] | 1874 |                     redfish::time_utils::getDateTimeUintMs(*updateTimestamp); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1875 |                 if (filePath != nullptr) | 
 | 1876 |                 { | 
 | 1877 |                     thisEntry["AdditionalDataURI"] = | 
 | 1878 |                         "/redfish/v1/Systems/system/LogServices/EventLog/Entries/" + | 
 | 1879 |                         std::to_string(*id) + "/attachment"; | 
 | 1880 |                 } | 
 | 1881 |             } | 
| Ed Tanous | 3544d2a | 2023-08-06 18:12:20 -0700 | [diff] [blame] | 1882 |             std::ranges::sort(entriesArray, [](const nlohmann::json& left, | 
 | 1883 |                                                const nlohmann::json& right) { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1884 |                 return (left["Id"] <= right["Id"]); | 
| Ed Tanous | 3544d2a | 2023-08-06 18:12:20 -0700 | [diff] [blame] | 1885 |             }); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1886 |             asyncResp->res.jsonValue["Members@odata.count"] = | 
 | 1887 |                 entriesArray.size(); | 
| Ed Tanous | 3544d2a | 2023-08-06 18:12:20 -0700 | [diff] [blame] | 1888 |             asyncResp->res.jsonValue["Members"] = std::move(entriesArray); | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 1889 |         }); | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 1890 |     }); | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 1891 | } | 
| Xiaochao Ma | 75710de | 2021-01-21 17:56:02 +0800 | [diff] [blame] | 1892 |  | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 1893 | inline void requestRoutesDBusEventLogEntry(App& app) | 
| Adriana Kobylak | 400fd1f | 2021-01-29 09:01:30 -0600 | [diff] [blame] | 1894 | { | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 1895 |     BMCWEB_ROUTE( | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 1896 |         app, "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/<str>/") | 
| Ed Tanous | ed39821 | 2021-06-09 17:05:54 -0700 | [diff] [blame] | 1897 |         .privileges(redfish::privileges::getLogEntry) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1898 |         .methods(boost::beast::http::verb::get)( | 
 | 1899 |             [&app](const crow::Request& req, | 
 | 1900 |                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 1901 |                    const std::string& systemName, const std::string& param) { | 
| Carson Labrado | 3ba0007 | 2022-06-06 19:40:56 +0000 | [diff] [blame] | 1902 |         if (!redfish::setUpRedfishRoute(app, req, asyncResp)) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1903 |         { | 
 | 1904 |             return; | 
 | 1905 |         } | 
| Ed Tanous | 7f3e84a | 2022-12-28 16:22:54 -0800 | [diff] [blame] | 1906 |         if constexpr (bmcwebEnableMultiHost) | 
 | 1907 |         { | 
 | 1908 |             // Option currently returns no systems.  TBD | 
 | 1909 |             messages::resourceNotFound(asyncResp->res, "ComputerSystem", | 
 | 1910 |                                        systemName); | 
 | 1911 |             return; | 
 | 1912 |         } | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 1913 |         if (systemName != "system") | 
 | 1914 |         { | 
 | 1915 |             messages::resourceNotFound(asyncResp->res, "ComputerSystem", | 
 | 1916 |                                        systemName); | 
 | 1917 |             return; | 
 | 1918 |         } | 
 | 1919 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1920 |         std::string entryID = param; | 
 | 1921 |         dbus::utility::escapePathForDbus(entryID); | 
 | 1922 |  | 
 | 1923 |         // DBus implementation of EventLog/Entries | 
 | 1924 |         // Make call to Logging Service to find all log entry objects | 
| Krzysztof Grobelny | d1bde9e | 2022-09-07 10:40:51 +0200 | [diff] [blame] | 1925 |         sdbusplus::asio::getAllProperties( | 
 | 1926 |             *crow::connections::systemBus, "xyz.openbmc_project.Logging", | 
 | 1927 |             "/xyz/openbmc_project/logging/entry/" + entryID, "", | 
| Ed Tanous | 5e7e2dc | 2023-02-16 10:37:01 -0800 | [diff] [blame] | 1928 |             [asyncResp, entryID](const boost::system::error_code& ec, | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1929 |                                  const dbus::utility::DBusPropertiesMap& resp) { | 
 | 1930 |             if (ec.value() == EBADR) | 
| Adriana Kobylak | 400fd1f | 2021-01-29 09:01:30 -0600 | [diff] [blame] | 1931 |             { | 
| Krzysztof Grobelny | d1bde9e | 2022-09-07 10:40:51 +0200 | [diff] [blame] | 1932 |                 messages::resourceNotFound(asyncResp->res, "EventLogEntry", | 
 | 1933 |                                            entryID); | 
| Ed Tanous | 45ca1b8 | 2022-03-25 13:07:27 -0700 | [diff] [blame] | 1934 |                 return; | 
 | 1935 |             } | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1936 |             if (ec) | 
 | 1937 |             { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1938 |                 BMCWEB_LOG_ERROR( | 
 | 1939 |                     "EventLogEntry (DBus) resp_handler got error {}", ec); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1940 |                 messages::internalError(asyncResp->res); | 
 | 1941 |                 return; | 
 | 1942 |             } | 
 | 1943 |             const uint32_t* id = nullptr; | 
 | 1944 |             const uint64_t* timestamp = nullptr; | 
 | 1945 |             const uint64_t* updateTimestamp = nullptr; | 
 | 1946 |             const std::string* severity = nullptr; | 
 | 1947 |             const std::string* message = nullptr; | 
 | 1948 |             const std::string* filePath = nullptr; | 
| Vijay Lobo | 9c11a17 | 2021-10-07 16:53:16 -0500 | [diff] [blame] | 1949 |             const std::string* resolution = nullptr; | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1950 |             bool resolved = false; | 
| Abhishek Patel | 9017faf | 2021-09-14 22:48:55 -0500 | [diff] [blame] | 1951 |             const std::string* notify = nullptr; | 
| Adriana Kobylak | 400fd1f | 2021-01-29 09:01:30 -0600 | [diff] [blame] | 1952 |  | 
| Krzysztof Grobelny | d1bde9e | 2022-09-07 10:40:51 +0200 | [diff] [blame] | 1953 |             const bool success = sdbusplus::unpackPropertiesNoThrow( | 
 | 1954 |                 dbus_utils::UnpackErrorPrinter(), resp, "Id", id, "Timestamp", | 
 | 1955 |                 timestamp, "UpdateTimestamp", updateTimestamp, "Severity", | 
| Vijay Lobo | 9c11a17 | 2021-10-07 16:53:16 -0500 | [diff] [blame] | 1956 |                 severity, "Message", message, "Resolved", resolved, | 
| Abhishek Patel | 9017faf | 2021-09-14 22:48:55 -0500 | [diff] [blame] | 1957 |                 "Resolution", resolution, "Path", filePath, | 
 | 1958 |                 "ServiceProviderNotify", notify); | 
| Krzysztof Grobelny | d1bde9e | 2022-09-07 10:40:51 +0200 | [diff] [blame] | 1959 |  | 
 | 1960 |             if (!success) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1961 |             { | 
| Krzysztof Grobelny | d1bde9e | 2022-09-07 10:40:51 +0200 | [diff] [blame] | 1962 |                 messages::internalError(asyncResp->res); | 
 | 1963 |                 return; | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1964 |             } | 
| Krzysztof Grobelny | d1bde9e | 2022-09-07 10:40:51 +0200 | [diff] [blame] | 1965 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1966 |             if (id == nullptr || message == nullptr || severity == nullptr || | 
| Abhishek Patel | 9017faf | 2021-09-14 22:48:55 -0500 | [diff] [blame] | 1967 |                 timestamp == nullptr || updateTimestamp == nullptr || | 
 | 1968 |                 notify == nullptr) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1969 |             { | 
 | 1970 |                 messages::internalError(asyncResp->res); | 
 | 1971 |                 return; | 
 | 1972 |             } | 
| Abhishek Patel | 9017faf | 2021-09-14 22:48:55 -0500 | [diff] [blame] | 1973 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1974 |             asyncResp->res.jsonValue["@odata.type"] = | 
| Vijay Lobo | 9c11a17 | 2021-10-07 16:53:16 -0500 | [diff] [blame] | 1975 |                 "#LogEntry.v1_9_0.LogEntry"; | 
| Ed Tanous | ef4c65b | 2023-04-24 15:28:50 -0700 | [diff] [blame] | 1976 |             asyncResp->res.jsonValue["@odata.id"] = boost::urls::format( | 
 | 1977 |                 "/redfish/v1/Systems/system/LogServices/EventLog/Entries/{}", | 
 | 1978 |                 std::to_string(*id)); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1979 |             asyncResp->res.jsonValue["Name"] = "System Event Log Entry"; | 
 | 1980 |             asyncResp->res.jsonValue["Id"] = std::to_string(*id); | 
 | 1981 |             asyncResp->res.jsonValue["Message"] = *message; | 
 | 1982 |             asyncResp->res.jsonValue["Resolved"] = resolved; | 
| Abhishek Patel | 9017faf | 2021-09-14 22:48:55 -0500 | [diff] [blame] | 1983 |             std::optional<bool> notifyAction = getProviderNotifyAction(*notify); | 
 | 1984 |             if (notifyAction) | 
 | 1985 |             { | 
 | 1986 |                 asyncResp->res.jsonValue["ServiceProviderNotified"] = | 
 | 1987 |                     *notifyAction; | 
 | 1988 |             } | 
| Vijay Lobo | 9c11a17 | 2021-10-07 16:53:16 -0500 | [diff] [blame] | 1989 |             if ((resolution != nullptr) && (!(*resolution).empty())) | 
 | 1990 |             { | 
 | 1991 |                 asyncResp->res.jsonValue["Resolution"] = *resolution; | 
 | 1992 |             } | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1993 |             asyncResp->res.jsonValue["EntryType"] = "Event"; | 
 | 1994 |             asyncResp->res.jsonValue["Severity"] = | 
 | 1995 |                 translateSeverityDbusToRedfish(*severity); | 
 | 1996 |             asyncResp->res.jsonValue["Created"] = | 
| Ed Tanous | 2b82937 | 2022-08-03 14:22:34 -0700 | [diff] [blame] | 1997 |                 redfish::time_utils::getDateTimeUintMs(*timestamp); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1998 |             asyncResp->res.jsonValue["Modified"] = | 
| Ed Tanous | 2b82937 | 2022-08-03 14:22:34 -0700 | [diff] [blame] | 1999 |                 redfish::time_utils::getDateTimeUintMs(*updateTimestamp); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2000 |             if (filePath != nullptr) | 
 | 2001 |             { | 
 | 2002 |                 asyncResp->res.jsonValue["AdditionalDataURI"] = | 
 | 2003 |                     "/redfish/v1/Systems/system/LogServices/EventLog/Entries/" + | 
 | 2004 |                     std::to_string(*id) + "/attachment"; | 
 | 2005 |             } | 
| Ed Tanous | 45ca1b8 | 2022-03-25 13:07:27 -0700 | [diff] [blame] | 2006 |         }); | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 2007 |     }); | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 2008 |  | 
 | 2009 |     BMCWEB_ROUTE( | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 2010 |         app, "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/<str>/") | 
| Ed Tanous | ed39821 | 2021-06-09 17:05:54 -0700 | [diff] [blame] | 2011 |         .privileges(redfish::privileges::patchLogEntry) | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 2012 |         .methods(boost::beast::http::verb::patch)( | 
| Ed Tanous | 45ca1b8 | 2022-03-25 13:07:27 -0700 | [diff] [blame] | 2013 |             [&app](const crow::Request& req, | 
 | 2014 |                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 2015 |                    const std::string& systemName, const std::string& entryId) { | 
| Carson Labrado | 3ba0007 | 2022-06-06 19:40:56 +0000 | [diff] [blame] | 2016 |         if (!redfish::setUpRedfishRoute(app, req, asyncResp)) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2017 |         { | 
 | 2018 |             return; | 
 | 2019 |         } | 
| Ed Tanous | 7f3e84a | 2022-12-28 16:22:54 -0800 | [diff] [blame] | 2020 |         if constexpr (bmcwebEnableMultiHost) | 
 | 2021 |         { | 
 | 2022 |             // Option currently returns no systems.  TBD | 
 | 2023 |             messages::resourceNotFound(asyncResp->res, "ComputerSystem", | 
 | 2024 |                                        systemName); | 
 | 2025 |             return; | 
 | 2026 |         } | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 2027 |         if (systemName != "system") | 
 | 2028 |         { | 
 | 2029 |             messages::resourceNotFound(asyncResp->res, "ComputerSystem", | 
 | 2030 |                                        systemName); | 
 | 2031 |             return; | 
 | 2032 |         } | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2033 |         std::optional<bool> resolved; | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 2034 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2035 |         if (!json_util::readJsonPatch(req, asyncResp->res, "Resolved", | 
 | 2036 |                                       resolved)) | 
 | 2037 |         { | 
 | 2038 |             return; | 
 | 2039 |         } | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2040 |         BMCWEB_LOG_DEBUG("Set Resolved"); | 
| Adriana Kobylak | 400fd1f | 2021-01-29 09:01:30 -0600 | [diff] [blame] | 2041 |  | 
| George Liu | 9ae226f | 2023-06-21 17:56:46 +0800 | [diff] [blame] | 2042 |         sdbusplus::asio::setProperty( | 
 | 2043 |             *crow::connections::systemBus, "xyz.openbmc_project.Logging", | 
 | 2044 |             "/xyz/openbmc_project/logging/entry/" + entryId, | 
 | 2045 |             "xyz.openbmc_project.Logging.Entry", "Resolved", *resolved, | 
| Ed Tanous | 5e7e2dc | 2023-02-16 10:37:01 -0800 | [diff] [blame] | 2046 |             [asyncResp, entryId](const boost::system::error_code& ec) { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2047 |             if (ec) | 
 | 2048 |             { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2049 |                 BMCWEB_LOG_DEBUG("DBUS response error {}", ec); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2050 |                 messages::internalError(asyncResp->res); | 
 | 2051 |                 return; | 
 | 2052 |             } | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2053 |         }); | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 2054 |     }); | 
| Adriana Kobylak | 400fd1f | 2021-01-29 09:01:30 -0600 | [diff] [blame] | 2055 |  | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 2056 |     BMCWEB_ROUTE( | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 2057 |         app, "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/<str>/") | 
| Ed Tanous | ed39821 | 2021-06-09 17:05:54 -0700 | [diff] [blame] | 2058 |         .privileges(redfish::privileges::deleteLogEntry) | 
 | 2059 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2060 |         .methods(boost::beast::http::verb::delete_)( | 
 | 2061 |             [&app](const crow::Request& req, | 
 | 2062 |                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 2063 |                    const std::string& systemName, const std::string& param) { | 
| Carson Labrado | 3ba0007 | 2022-06-06 19:40:56 +0000 | [diff] [blame] | 2064 |         if (!redfish::setUpRedfishRoute(app, req, asyncResp)) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2065 |         { | 
 | 2066 |             return; | 
 | 2067 |         } | 
| Ed Tanous | 7f3e84a | 2022-12-28 16:22:54 -0800 | [diff] [blame] | 2068 |         if constexpr (bmcwebEnableMultiHost) | 
 | 2069 |         { | 
 | 2070 |             // Option currently returns no systems.  TBD | 
 | 2071 |             messages::resourceNotFound(asyncResp->res, "ComputerSystem", | 
 | 2072 |                                        systemName); | 
 | 2073 |             return; | 
 | 2074 |         } | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 2075 |         if (systemName != "system") | 
 | 2076 |         { | 
 | 2077 |             messages::resourceNotFound(asyncResp->res, "ComputerSystem", | 
 | 2078 |                                        systemName); | 
 | 2079 |             return; | 
 | 2080 |         } | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2081 |         BMCWEB_LOG_DEBUG("Do delete single event entries."); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2082 |  | 
 | 2083 |         std::string entryID = param; | 
 | 2084 |  | 
 | 2085 |         dbus::utility::escapePathForDbus(entryID); | 
 | 2086 |  | 
 | 2087 |         // Process response from Logging service. | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 2088 |         auto respHandler = [asyncResp, | 
 | 2089 |                             entryID](const boost::system::error_code& ec) { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2090 |             BMCWEB_LOG_DEBUG("EventLogEntry (DBus) doDelete callback: Done"); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2091 |             if (ec) | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 2092 |             { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2093 |                 if (ec.value() == EBADR) | 
| Ed Tanous | 45ca1b8 | 2022-03-25 13:07:27 -0700 | [diff] [blame] | 2094 |                 { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2095 |                     messages::resourceNotFound(asyncResp->res, "LogEntry", | 
 | 2096 |                                                entryID); | 
| Ed Tanous | 45ca1b8 | 2022-03-25 13:07:27 -0700 | [diff] [blame] | 2097 |                     return; | 
 | 2098 |                 } | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2099 |                 // TODO Handle for specific error code | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2100 |                 BMCWEB_LOG_ERROR( | 
 | 2101 |                     "EventLogEntry (DBus) doDelete respHandler got error {}", | 
 | 2102 |                     ec); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2103 |                 asyncResp->res.result( | 
 | 2104 |                     boost::beast::http::status::internal_server_error); | 
 | 2105 |                 return; | 
 | 2106 |             } | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 2107 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2108 |             asyncResp->res.result(boost::beast::http::status::ok); | 
 | 2109 |         }; | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 2110 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2111 |         // Make call to Logging service to request Delete Log | 
 | 2112 |         crow::connections::systemBus->async_method_call( | 
 | 2113 |             respHandler, "xyz.openbmc_project.Logging", | 
 | 2114 |             "/xyz/openbmc_project/logging/entry/" + entryID, | 
 | 2115 |             "xyz.openbmc_project.Object.Delete", "Delete"); | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 2116 |     }); | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 2117 | } | 
 | 2118 |  | 
| Spencer Ku | b7028eb | 2021-10-26 15:27:35 +0800 | [diff] [blame] | 2119 | constexpr const char* hostLoggerFolderPath = "/var/log/console"; | 
 | 2120 |  | 
 | 2121 | inline bool | 
 | 2122 |     getHostLoggerFiles(const std::string& hostLoggerFilePath, | 
 | 2123 |                        std::vector<std::filesystem::path>& hostLoggerFiles) | 
 | 2124 | { | 
 | 2125 |     std::error_code ec; | 
 | 2126 |     std::filesystem::directory_iterator logPath(hostLoggerFilePath, ec); | 
 | 2127 |     if (ec) | 
 | 2128 |     { | 
| Carson Labrado | bf2dded | 2023-08-10 00:37:06 +0000 | [diff] [blame] | 2129 |         BMCWEB_LOG_WARNING("{}", ec.message()); | 
| Spencer Ku | b7028eb | 2021-10-26 15:27:35 +0800 | [diff] [blame] | 2130 |         return false; | 
 | 2131 |     } | 
 | 2132 |     for (const std::filesystem::directory_entry& it : logPath) | 
 | 2133 |     { | 
 | 2134 |         std::string filename = it.path().filename(); | 
 | 2135 |         // Prefix of each log files is "log". Find the file and save the | 
 | 2136 |         // path | 
| Ed Tanous | 11ba397 | 2022-07-11 09:50:41 -0700 | [diff] [blame] | 2137 |         if (filename.starts_with("log")) | 
| Spencer Ku | b7028eb | 2021-10-26 15:27:35 +0800 | [diff] [blame] | 2138 |         { | 
 | 2139 |             hostLoggerFiles.emplace_back(it.path()); | 
 | 2140 |         } | 
 | 2141 |     } | 
 | 2142 |     // As the log files rotate, they are appended with a ".#" that is higher for | 
 | 2143 |     // the older logs. Since we start from oldest logs, sort the name in | 
 | 2144 |     // descending order. | 
 | 2145 |     std::sort(hostLoggerFiles.rbegin(), hostLoggerFiles.rend(), | 
 | 2146 |               AlphanumLess<std::string>()); | 
 | 2147 |  | 
 | 2148 |     return true; | 
 | 2149 | } | 
 | 2150 |  | 
| Ed Tanous | 02cad96 | 2022-06-30 16:50:15 -0700 | [diff] [blame] | 2151 | inline bool getHostLoggerEntries( | 
 | 2152 |     const std::vector<std::filesystem::path>& hostLoggerFiles, uint64_t skip, | 
 | 2153 |     uint64_t top, std::vector<std::string>& logEntries, size_t& logCount) | 
| Spencer Ku | b7028eb | 2021-10-26 15:27:35 +0800 | [diff] [blame] | 2154 | { | 
 | 2155 |     GzFileReader logFile; | 
 | 2156 |  | 
 | 2157 |     // Go though all log files and expose host logs. | 
 | 2158 |     for (const std::filesystem::path& it : hostLoggerFiles) | 
 | 2159 |     { | 
 | 2160 |         if (!logFile.gzGetLines(it.string(), skip, top, logEntries, logCount)) | 
 | 2161 |         { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2162 |             BMCWEB_LOG_ERROR("fail to expose host logs"); | 
| Spencer Ku | b7028eb | 2021-10-26 15:27:35 +0800 | [diff] [blame] | 2163 |             return false; | 
 | 2164 |         } | 
 | 2165 |     } | 
 | 2166 |     // Get lastMessage from constructor by getter | 
 | 2167 |     std::string lastMessage = logFile.getLastMessage(); | 
 | 2168 |     if (!lastMessage.empty()) | 
 | 2169 |     { | 
 | 2170 |         logCount++; | 
 | 2171 |         if (logCount > skip && logCount <= (skip + top)) | 
 | 2172 |         { | 
 | 2173 |             logEntries.push_back(lastMessage); | 
 | 2174 |         } | 
 | 2175 |     } | 
 | 2176 |     return true; | 
 | 2177 | } | 
 | 2178 |  | 
 | 2179 | inline void fillHostLoggerEntryJson(const std::string& logEntryID, | 
 | 2180 |                                     const std::string& msg, | 
| Jason M. Bills | 6d6574c | 2022-06-28 12:30:16 -0700 | [diff] [blame] | 2181 |                                     nlohmann::json::object_t& logEntryJson) | 
| Spencer Ku | b7028eb | 2021-10-26 15:27:35 +0800 | [diff] [blame] | 2182 | { | 
 | 2183 |     // Fill in the log entry with the gathered data. | 
| Vijay Lobo | 9c11a17 | 2021-10-07 16:53:16 -0500 | [diff] [blame] | 2184 |     logEntryJson["@odata.type"] = "#LogEntry.v1_9_0.LogEntry"; | 
| Ed Tanous | ef4c65b | 2023-04-24 15:28:50 -0700 | [diff] [blame] | 2185 |     logEntryJson["@odata.id"] = boost::urls::format( | 
 | 2186 |         "/redfish/v1/Systems/system/LogServices/HostLogger/Entries/{}", | 
 | 2187 |         logEntryID); | 
| Jason M. Bills | 6d6574c | 2022-06-28 12:30:16 -0700 | [diff] [blame] | 2188 |     logEntryJson["Name"] = "Host Logger Entry"; | 
 | 2189 |     logEntryJson["Id"] = logEntryID; | 
 | 2190 |     logEntryJson["Message"] = msg; | 
 | 2191 |     logEntryJson["EntryType"] = "Oem"; | 
 | 2192 |     logEntryJson["Severity"] = "OK"; | 
 | 2193 |     logEntryJson["OemRecordFormat"] = "Host Logger Entry"; | 
| Spencer Ku | b7028eb | 2021-10-26 15:27:35 +0800 | [diff] [blame] | 2194 | } | 
 | 2195 |  | 
 | 2196 | inline void requestRoutesSystemHostLogger(App& app) | 
 | 2197 | { | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 2198 |     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/HostLogger/") | 
| Spencer Ku | b7028eb | 2021-10-26 15:27:35 +0800 | [diff] [blame] | 2199 |         .privileges(redfish::privileges::getLogService) | 
| Ed Tanous | 1476687 | 2022-03-15 10:44:42 -0700 | [diff] [blame] | 2200 |         .methods(boost::beast::http::verb::get)( | 
 | 2201 |             [&app](const crow::Request& req, | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 2202 |                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 2203 |                    const std::string& systemName) { | 
| Carson Labrado | 3ba0007 | 2022-06-06 19:40:56 +0000 | [diff] [blame] | 2204 |         if (!redfish::setUpRedfishRoute(app, req, asyncResp)) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2205 |         { | 
 | 2206 |             return; | 
 | 2207 |         } | 
| Ed Tanous | 7f3e84a | 2022-12-28 16:22:54 -0800 | [diff] [blame] | 2208 |         if constexpr (bmcwebEnableMultiHost) | 
 | 2209 |         { | 
 | 2210 |             // Option currently returns no systems.  TBD | 
 | 2211 |             messages::resourceNotFound(asyncResp->res, "ComputerSystem", | 
 | 2212 |                                        systemName); | 
 | 2213 |             return; | 
 | 2214 |         } | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 2215 |         if (systemName != "system") | 
 | 2216 |         { | 
 | 2217 |             messages::resourceNotFound(asyncResp->res, "ComputerSystem", | 
 | 2218 |                                        systemName); | 
 | 2219 |             return; | 
 | 2220 |         } | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2221 |         asyncResp->res.jsonValue["@odata.id"] = | 
 | 2222 |             "/redfish/v1/Systems/system/LogServices/HostLogger"; | 
 | 2223 |         asyncResp->res.jsonValue["@odata.type"] = | 
| Janet Adkins | b25644a | 2023-08-16 11:23:45 -0500 | [diff] [blame] | 2224 |             "#LogService.v1_2_0.LogService"; | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2225 |         asyncResp->res.jsonValue["Name"] = "Host Logger Service"; | 
 | 2226 |         asyncResp->res.jsonValue["Description"] = "Host Logger Service"; | 
 | 2227 |         asyncResp->res.jsonValue["Id"] = "HostLogger"; | 
 | 2228 |         asyncResp->res.jsonValue["Entries"]["@odata.id"] = | 
 | 2229 |             "/redfish/v1/Systems/system/LogServices/HostLogger/Entries"; | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 2230 |     }); | 
| Spencer Ku | b7028eb | 2021-10-26 15:27:35 +0800 | [diff] [blame] | 2231 | } | 
 | 2232 |  | 
 | 2233 | inline void requestRoutesSystemHostLoggerCollection(App& app) | 
 | 2234 | { | 
 | 2235 |     BMCWEB_ROUTE(app, | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 2236 |                  "/redfish/v1/Systems/<str>/LogServices/HostLogger/Entries/") | 
| Spencer Ku | b7028eb | 2021-10-26 15:27:35 +0800 | [diff] [blame] | 2237 |         .privileges(redfish::privileges::getLogEntry) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2238 |         .methods(boost::beast::http::verb::get)( | 
 | 2239 |             [&app](const crow::Request& req, | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 2240 |                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 2241 |                    const std::string& systemName) { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2242 |         query_param::QueryCapabilities capabilities = { | 
 | 2243 |             .canDelegateTop = true, | 
 | 2244 |             .canDelegateSkip = true, | 
 | 2245 |         }; | 
 | 2246 |         query_param::Query delegatedQuery; | 
 | 2247 |         if (!redfish::setUpRedfishRouteWithDelegation( | 
| Carson Labrado | 3ba0007 | 2022-06-06 19:40:56 +0000 | [diff] [blame] | 2248 |                 app, req, asyncResp, delegatedQuery, capabilities)) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2249 |         { | 
 | 2250 |             return; | 
 | 2251 |         } | 
| Ed Tanous | 7f3e84a | 2022-12-28 16:22:54 -0800 | [diff] [blame] | 2252 |         if constexpr (bmcwebEnableMultiHost) | 
 | 2253 |         { | 
 | 2254 |             // Option currently returns no systems.  TBD | 
 | 2255 |             messages::resourceNotFound(asyncResp->res, "ComputerSystem", | 
 | 2256 |                                        systemName); | 
 | 2257 |             return; | 
 | 2258 |         } | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 2259 |         if (systemName != "system") | 
 | 2260 |         { | 
 | 2261 |             messages::resourceNotFound(asyncResp->res, "ComputerSystem", | 
 | 2262 |                                        systemName); | 
 | 2263 |             return; | 
 | 2264 |         } | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2265 |         asyncResp->res.jsonValue["@odata.id"] = | 
 | 2266 |             "/redfish/v1/Systems/system/LogServices/HostLogger/Entries"; | 
 | 2267 |         asyncResp->res.jsonValue["@odata.type"] = | 
 | 2268 |             "#LogEntryCollection.LogEntryCollection"; | 
 | 2269 |         asyncResp->res.jsonValue["Name"] = "HostLogger Entries"; | 
 | 2270 |         asyncResp->res.jsonValue["Description"] = | 
 | 2271 |             "Collection of HostLogger Entries"; | 
 | 2272 |         nlohmann::json& logEntryArray = asyncResp->res.jsonValue["Members"]; | 
 | 2273 |         logEntryArray = nlohmann::json::array(); | 
 | 2274 |         asyncResp->res.jsonValue["Members@odata.count"] = 0; | 
| Spencer Ku | b7028eb | 2021-10-26 15:27:35 +0800 | [diff] [blame] | 2275 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2276 |         std::vector<std::filesystem::path> hostLoggerFiles; | 
 | 2277 |         if (!getHostLoggerFiles(hostLoggerFolderPath, hostLoggerFiles)) | 
 | 2278 |         { | 
| Carson Labrado | bf2dded | 2023-08-10 00:37:06 +0000 | [diff] [blame] | 2279 |             BMCWEB_LOG_DEBUG("Failed to get host log file path"); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2280 |             return; | 
 | 2281 |         } | 
| Ed Tanous | 3648c8b | 2022-07-25 13:39:59 -0700 | [diff] [blame] | 2282 |         // If we weren't provided top and skip limits, use the defaults. | 
 | 2283 |         size_t skip = delegatedQuery.skip.value_or(0); | 
| Jiaqing Zhao | 5143f7a | 2022-07-22 09:33:33 +0800 | [diff] [blame] | 2284 |         size_t top = delegatedQuery.top.value_or(query_param::Query::maxTop); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2285 |         size_t logCount = 0; | 
 | 2286 |         // This vector only store the entries we want to expose that | 
 | 2287 |         // control by skip and top. | 
 | 2288 |         std::vector<std::string> logEntries; | 
| Ed Tanous | 3648c8b | 2022-07-25 13:39:59 -0700 | [diff] [blame] | 2289 |         if (!getHostLoggerEntries(hostLoggerFiles, skip, top, logEntries, | 
 | 2290 |                                   logCount)) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2291 |         { | 
 | 2292 |             messages::internalError(asyncResp->res); | 
 | 2293 |             return; | 
 | 2294 |         } | 
 | 2295 |         // If vector is empty, that means skip value larger than total | 
 | 2296 |         // log count | 
 | 2297 |         if (logEntries.empty()) | 
 | 2298 |         { | 
 | 2299 |             asyncResp->res.jsonValue["Members@odata.count"] = logCount; | 
 | 2300 |             return; | 
 | 2301 |         } | 
 | 2302 |         if (!logEntries.empty()) | 
 | 2303 |         { | 
 | 2304 |             for (size_t i = 0; i < logEntries.size(); i++) | 
| George Liu | 0fda0f1 | 2021-11-16 10:06:17 +0800 | [diff] [blame] | 2305 |             { | 
| Jason M. Bills | 6d6574c | 2022-06-28 12:30:16 -0700 | [diff] [blame] | 2306 |                 nlohmann::json::object_t hostLogEntry; | 
| Ed Tanous | 3648c8b | 2022-07-25 13:39:59 -0700 | [diff] [blame] | 2307 |                 fillHostLoggerEntryJson(std::to_string(skip + i), logEntries[i], | 
 | 2308 |                                         hostLogEntry); | 
| Patrick Williams | b2ba307 | 2023-05-12 10:27:39 -0500 | [diff] [blame] | 2309 |                 logEntryArray.emplace_back(std::move(hostLogEntry)); | 
| George Liu | 0fda0f1 | 2021-11-16 10:06:17 +0800 | [diff] [blame] | 2310 |             } | 
 | 2311 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2312 |             asyncResp->res.jsonValue["Members@odata.count"] = logCount; | 
| Ed Tanous | 3648c8b | 2022-07-25 13:39:59 -0700 | [diff] [blame] | 2313 |             if (skip + top < logCount) | 
| George Liu | 0fda0f1 | 2021-11-16 10:06:17 +0800 | [diff] [blame] | 2314 |             { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2315 |                 asyncResp->res.jsonValue["Members@odata.nextLink"] = | 
 | 2316 |                     "/redfish/v1/Systems/system/LogServices/HostLogger/Entries?$skip=" + | 
| Ed Tanous | 3648c8b | 2022-07-25 13:39:59 -0700 | [diff] [blame] | 2317 |                     std::to_string(skip + top); | 
| George Liu | 0fda0f1 | 2021-11-16 10:06:17 +0800 | [diff] [blame] | 2318 |             } | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2319 |         } | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 2320 |     }); | 
| Spencer Ku | b7028eb | 2021-10-26 15:27:35 +0800 | [diff] [blame] | 2321 | } | 
 | 2322 |  | 
 | 2323 | inline void requestRoutesSystemHostLoggerLogEntry(App& app) | 
 | 2324 | { | 
 | 2325 |     BMCWEB_ROUTE( | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 2326 |         app, "/redfish/v1/Systems/<str>/LogServices/HostLogger/Entries/<str>/") | 
| Spencer Ku | b7028eb | 2021-10-26 15:27:35 +0800 | [diff] [blame] | 2327 |         .privileges(redfish::privileges::getLogEntry) | 
 | 2328 |         .methods(boost::beast::http::verb::get)( | 
| Ed Tanous | 45ca1b8 | 2022-03-25 13:07:27 -0700 | [diff] [blame] | 2329 |             [&app](const crow::Request& req, | 
 | 2330 |                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 2331 |                    const std::string& systemName, const std::string& param) { | 
| Carson Labrado | 3ba0007 | 2022-06-06 19:40:56 +0000 | [diff] [blame] | 2332 |         if (!redfish::setUpRedfishRoute(app, req, asyncResp)) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2333 |         { | 
 | 2334 |             return; | 
 | 2335 |         } | 
| Ed Tanous | 7f3e84a | 2022-12-28 16:22:54 -0800 | [diff] [blame] | 2336 |         if constexpr (bmcwebEnableMultiHost) | 
 | 2337 |         { | 
 | 2338 |             // Option currently returns no systems.  TBD | 
 | 2339 |             messages::resourceNotFound(asyncResp->res, "ComputerSystem", | 
 | 2340 |                                        systemName); | 
 | 2341 |             return; | 
 | 2342 |         } | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 2343 |         if (systemName != "system") | 
 | 2344 |         { | 
 | 2345 |             messages::resourceNotFound(asyncResp->res, "ComputerSystem", | 
 | 2346 |                                        systemName); | 
 | 2347 |             return; | 
 | 2348 |         } | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2349 |         const std::string& targetID = param; | 
| Spencer Ku | b7028eb | 2021-10-26 15:27:35 +0800 | [diff] [blame] | 2350 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2351 |         uint64_t idInt = 0; | 
| Ed Tanous | ca45aa3 | 2022-01-07 09:28:45 -0800 | [diff] [blame] | 2352 |  | 
| Patrick Williams | 84396af | 2023-05-11 11:47:45 -0500 | [diff] [blame] | 2353 |         auto [ptr, ec] = std::from_chars(&*targetID.begin(), &*targetID.end(), | 
 | 2354 |                                          idInt); | 
| Jiaqing Zhao | 9db4ba2 | 2022-10-09 17:24:40 +0800 | [diff] [blame] | 2355 |         if (ec == std::errc::invalid_argument || | 
 | 2356 |             ec == std::errc::result_out_of_range) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2357 |         { | 
| Jiaqing Zhao | 9db4ba2 | 2022-10-09 17:24:40 +0800 | [diff] [blame] | 2358 |             messages::resourceNotFound(asyncResp->res, "LogEntry", param); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2359 |             return; | 
 | 2360 |         } | 
| Spencer Ku | b7028eb | 2021-10-26 15:27:35 +0800 | [diff] [blame] | 2361 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2362 |         std::vector<std::filesystem::path> hostLoggerFiles; | 
 | 2363 |         if (!getHostLoggerFiles(hostLoggerFolderPath, hostLoggerFiles)) | 
 | 2364 |         { | 
| Carson Labrado | bf2dded | 2023-08-10 00:37:06 +0000 | [diff] [blame] | 2365 |             BMCWEB_LOG_DEBUG("Failed to get host log file path"); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2366 |             return; | 
 | 2367 |         } | 
| Spencer Ku | b7028eb | 2021-10-26 15:27:35 +0800 | [diff] [blame] | 2368 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2369 |         size_t logCount = 0; | 
| Ed Tanous | 3648c8b | 2022-07-25 13:39:59 -0700 | [diff] [blame] | 2370 |         size_t top = 1; | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2371 |         std::vector<std::string> logEntries; | 
 | 2372 |         // We can get specific entry by skip and top. For example, if we | 
 | 2373 |         // want to get nth entry, we can set skip = n-1 and top = 1 to | 
 | 2374 |         // get that entry | 
 | 2375 |         if (!getHostLoggerEntries(hostLoggerFiles, idInt, top, logEntries, | 
 | 2376 |                                   logCount)) | 
 | 2377 |         { | 
 | 2378 |             messages::internalError(asyncResp->res); | 
 | 2379 |             return; | 
 | 2380 |         } | 
| Spencer Ku | b7028eb | 2021-10-26 15:27:35 +0800 | [diff] [blame] | 2381 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2382 |         if (!logEntries.empty()) | 
 | 2383 |         { | 
| Jason M. Bills | 6d6574c | 2022-06-28 12:30:16 -0700 | [diff] [blame] | 2384 |             nlohmann::json::object_t hostLogEntry; | 
 | 2385 |             fillHostLoggerEntryJson(targetID, logEntries[0], hostLogEntry); | 
 | 2386 |             asyncResp->res.jsonValue.update(hostLogEntry); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2387 |             return; | 
 | 2388 |         } | 
| Spencer Ku | b7028eb | 2021-10-26 15:27:35 +0800 | [diff] [blame] | 2389 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2390 |         // Requested ID was not found | 
| Jiaqing Zhao | 9db4ba2 | 2022-10-09 17:24:40 +0800 | [diff] [blame] | 2391 |         messages::resourceNotFound(asyncResp->res, "LogEntry", param); | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 2392 |     }); | 
| Spencer Ku | b7028eb | 2021-10-26 15:27:35 +0800 | [diff] [blame] | 2393 | } | 
 | 2394 |  | 
| Claire Weinan | dd72e87 | 2022-08-15 14:20:06 -0700 | [diff] [blame] | 2395 | inline void handleBMCLogServicesCollectionGet( | 
| Claire Weinan | fdd2690 | 2022-03-01 14:18:25 -0800 | [diff] [blame] | 2396 |     crow::App& app, const crow::Request& req, | 
 | 2397 |     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) | 
 | 2398 | { | 
 | 2399 |     if (!redfish::setUpRedfishRoute(app, req, asyncResp)) | 
 | 2400 |     { | 
 | 2401 |         return; | 
 | 2402 |     } | 
 | 2403 |     // Collections don't include the static data added by SubRoute | 
 | 2404 |     // because it has a duplicate entry for members | 
 | 2405 |     asyncResp->res.jsonValue["@odata.type"] = | 
 | 2406 |         "#LogServiceCollection.LogServiceCollection"; | 
 | 2407 |     asyncResp->res.jsonValue["@odata.id"] = | 
 | 2408 |         "/redfish/v1/Managers/bmc/LogServices"; | 
 | 2409 |     asyncResp->res.jsonValue["Name"] = "Open BMC Log Services Collection"; | 
 | 2410 |     asyncResp->res.jsonValue["Description"] = | 
 | 2411 |         "Collection of LogServices for this Manager"; | 
 | 2412 |     nlohmann::json& logServiceArray = asyncResp->res.jsonValue["Members"]; | 
 | 2413 |     logServiceArray = nlohmann::json::array(); | 
 | 2414 |  | 
 | 2415 | #ifdef BMCWEB_ENABLE_REDFISH_BMC_JOURNAL | 
| Ed Tanous | 613dabe | 2022-07-09 11:17:36 -0700 | [diff] [blame] | 2416 |     nlohmann::json::object_t journal; | 
 | 2417 |     journal["@odata.id"] = "/redfish/v1/Managers/bmc/LogServices/Journal"; | 
| Patrick Williams | b2ba307 | 2023-05-12 10:27:39 -0500 | [diff] [blame] | 2418 |     logServiceArray.emplace_back(std::move(journal)); | 
| Claire Weinan | fdd2690 | 2022-03-01 14:18:25 -0800 | [diff] [blame] | 2419 | #endif | 
 | 2420 |  | 
 | 2421 |     asyncResp->res.jsonValue["Members@odata.count"] = logServiceArray.size(); | 
 | 2422 |  | 
 | 2423 | #ifdef BMCWEB_ENABLE_REDFISH_DUMP_LOG | 
| George Liu | 1591215 | 2023-01-11 10:18:18 +0800 | [diff] [blame] | 2424 |     constexpr std::array<std::string_view, 1> interfaces = { | 
| George Liu | 7a1dbc4 | 2022-12-07 16:03:22 +0800 | [diff] [blame] | 2425 |         "xyz.openbmc_project.Collection.DeleteAll"}; | 
 | 2426 |     dbus::utility::getSubTreePaths( | 
 | 2427 |         "/xyz/openbmc_project/dump", 0, interfaces, | 
| Claire Weinan | fdd2690 | 2022-03-01 14:18:25 -0800 | [diff] [blame] | 2428 |         [asyncResp]( | 
| George Liu | 7a1dbc4 | 2022-12-07 16:03:22 +0800 | [diff] [blame] | 2429 |             const boost::system::error_code& ec, | 
| Claire Weinan | fdd2690 | 2022-03-01 14:18:25 -0800 | [diff] [blame] | 2430 |             const dbus::utility::MapperGetSubTreePathsResponse& subTreePaths) { | 
 | 2431 |         if (ec) | 
 | 2432 |         { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2433 |             BMCWEB_LOG_ERROR( | 
 | 2434 |                 "handleBMCLogServicesCollectionGet respHandler got error {}", | 
 | 2435 |                 ec); | 
| Claire Weinan | fdd2690 | 2022-03-01 14:18:25 -0800 | [diff] [blame] | 2436 |             // Assume that getting an error simply means there are no dump | 
 | 2437 |             // LogServices. Return without adding any error response. | 
 | 2438 |             return; | 
 | 2439 |         } | 
 | 2440 |  | 
 | 2441 |         nlohmann::json& logServiceArrayLocal = | 
 | 2442 |             asyncResp->res.jsonValue["Members"]; | 
 | 2443 |  | 
 | 2444 |         for (const std::string& path : subTreePaths) | 
 | 2445 |         { | 
 | 2446 |             if (path == "/xyz/openbmc_project/dump/bmc") | 
 | 2447 |             { | 
| Ed Tanous | 613dabe | 2022-07-09 11:17:36 -0700 | [diff] [blame] | 2448 |                 nlohmann::json::object_t member; | 
 | 2449 |                 member["@odata.id"] = | 
 | 2450 |                     "/redfish/v1/Managers/bmc/LogServices/Dump"; | 
| Patrick Williams | b2ba307 | 2023-05-12 10:27:39 -0500 | [diff] [blame] | 2451 |                 logServiceArrayLocal.emplace_back(std::move(member)); | 
| Claire Weinan | fdd2690 | 2022-03-01 14:18:25 -0800 | [diff] [blame] | 2452 |             } | 
 | 2453 |             else if (path == "/xyz/openbmc_project/dump/faultlog") | 
 | 2454 |             { | 
| Ed Tanous | 613dabe | 2022-07-09 11:17:36 -0700 | [diff] [blame] | 2455 |                 nlohmann::json::object_t member; | 
 | 2456 |                 member["@odata.id"] = | 
 | 2457 |                     "/redfish/v1/Managers/bmc/LogServices/FaultLog"; | 
| Patrick Williams | b2ba307 | 2023-05-12 10:27:39 -0500 | [diff] [blame] | 2458 |                 logServiceArrayLocal.emplace_back(std::move(member)); | 
| Claire Weinan | fdd2690 | 2022-03-01 14:18:25 -0800 | [diff] [blame] | 2459 |             } | 
 | 2460 |         } | 
 | 2461 |  | 
 | 2462 |         asyncResp->res.jsonValue["Members@odata.count"] = | 
 | 2463 |             logServiceArrayLocal.size(); | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 2464 |     }); | 
| Claire Weinan | fdd2690 | 2022-03-01 14:18:25 -0800 | [diff] [blame] | 2465 | #endif | 
 | 2466 | } | 
 | 2467 |  | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 2468 | inline void requestRoutesBMCLogServiceCollection(App& app) | 
 | 2469 | { | 
 | 2470 |     BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/LogServices/") | 
| Gunnar Mills | ad89dcf | 2021-07-30 14:40:11 -0500 | [diff] [blame] | 2471 |         .privileges(redfish::privileges::getLogServiceCollection) | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 2472 |         .methods(boost::beast::http::verb::get)( | 
| Claire Weinan | dd72e87 | 2022-08-15 14:20:06 -0700 | [diff] [blame] | 2473 |             std::bind_front(handleBMCLogServicesCollectionGet, std::ref(app))); | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 2474 | } | 
| Ed Tanous | 1da66f7 | 2018-07-27 16:13:37 -0700 | [diff] [blame] | 2475 |  | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 2476 | inline void requestRoutesBMCJournalLogService(App& app) | 
| Ed Tanous | 1da66f7 | 2018-07-27 16:13:37 -0700 | [diff] [blame] | 2477 | { | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 2478 |     BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/LogServices/Journal/") | 
| Ed Tanous | ed39821 | 2021-06-09 17:05:54 -0700 | [diff] [blame] | 2479 |         .privileges(redfish::privileges::getLogService) | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 2480 |         .methods(boost::beast::http::verb::get)( | 
| Ed Tanous | 45ca1b8 | 2022-03-25 13:07:27 -0700 | [diff] [blame] | 2481 |             [&app](const crow::Request& req, | 
 | 2482 |                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { | 
| Carson Labrado | 3ba0007 | 2022-06-06 19:40:56 +0000 | [diff] [blame] | 2483 |         if (!redfish::setUpRedfishRoute(app, req, asyncResp)) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2484 |         { | 
 | 2485 |             return; | 
 | 2486 |         } | 
 | 2487 |         asyncResp->res.jsonValue["@odata.type"] = | 
| Janet Adkins | b25644a | 2023-08-16 11:23:45 -0500 | [diff] [blame] | 2488 |             "#LogService.v1_2_0.LogService"; | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2489 |         asyncResp->res.jsonValue["@odata.id"] = | 
 | 2490 |             "/redfish/v1/Managers/bmc/LogServices/Journal"; | 
 | 2491 |         asyncResp->res.jsonValue["Name"] = "Open BMC Journal Log Service"; | 
 | 2492 |         asyncResp->res.jsonValue["Description"] = "BMC Journal Log Service"; | 
| Ed Tanous | ed34a4a | 2023-02-08 15:43:27 -0800 | [diff] [blame] | 2493 |         asyncResp->res.jsonValue["Id"] = "Journal"; | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2494 |         asyncResp->res.jsonValue["OverWritePolicy"] = "WrapsWhenFull"; | 
| Tejas Patil | 7c8c405 | 2021-06-04 17:43:14 +0530 | [diff] [blame] | 2495 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2496 |         std::pair<std::string, std::string> redfishDateTimeOffset = | 
| Ed Tanous | 2b82937 | 2022-08-03 14:22:34 -0700 | [diff] [blame] | 2497 |             redfish::time_utils::getDateTimeOffsetNow(); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2498 |         asyncResp->res.jsonValue["DateTime"] = redfishDateTimeOffset.first; | 
 | 2499 |         asyncResp->res.jsonValue["DateTimeLocalOffset"] = | 
 | 2500 |             redfishDateTimeOffset.second; | 
| Tejas Patil | 7c8c405 | 2021-06-04 17:43:14 +0530 | [diff] [blame] | 2501 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2502 |         asyncResp->res.jsonValue["Entries"]["@odata.id"] = | 
 | 2503 |             "/redfish/v1/Managers/bmc/LogServices/Journal/Entries"; | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 2504 |     }); | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 2505 | } | 
| Jason M. Bills | e1f2634 | 2018-07-18 12:12:00 -0700 | [diff] [blame] | 2506 |  | 
| Jason M. Bills | 3a48b3a | 2022-06-24 10:10:15 -0700 | [diff] [blame] | 2507 | static int | 
 | 2508 |     fillBMCJournalLogEntryJson(const std::string& bmcJournalLogEntryID, | 
 | 2509 |                                sd_journal* journal, | 
 | 2510 |                                nlohmann::json::object_t& bmcJournalLogEntryJson) | 
| Jason M. Bills | e1f2634 | 2018-07-18 12:12:00 -0700 | [diff] [blame] | 2511 | { | 
 | 2512 |     // Get the Log Entry contents | 
 | 2513 |     int ret = 0; | 
| Jason M. Bills | e1f2634 | 2018-07-18 12:12:00 -0700 | [diff] [blame] | 2514 |  | 
| Jason M. Bills | a8fe54f | 2020-11-20 15:57:55 -0800 | [diff] [blame] | 2515 |     std::string message; | 
 | 2516 |     std::string_view syslogID; | 
 | 2517 |     ret = getJournalMetadata(journal, "SYSLOG_IDENTIFIER", syslogID); | 
 | 2518 |     if (ret < 0) | 
 | 2519 |     { | 
| Carson Labrado | bf2dded | 2023-08-10 00:37:06 +0000 | [diff] [blame] | 2520 |         BMCWEB_LOG_DEBUG("Failed to read SYSLOG_IDENTIFIER field: {}", | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2521 |                          strerror(-ret)); | 
| Jason M. Bills | a8fe54f | 2020-11-20 15:57:55 -0800 | [diff] [blame] | 2522 |     } | 
 | 2523 |     if (!syslogID.empty()) | 
 | 2524 |     { | 
 | 2525 |         message += std::string(syslogID) + ": "; | 
 | 2526 |     } | 
 | 2527 |  | 
| Ed Tanous | 39e7750 | 2019-03-04 17:35:53 -0800 | [diff] [blame] | 2528 |     std::string_view msg; | 
| Jason M. Bills | 16428a1 | 2018-11-02 12:42:29 -0700 | [diff] [blame] | 2529 |     ret = getJournalMetadata(journal, "MESSAGE", msg); | 
| Jason M. Bills | e1f2634 | 2018-07-18 12:12:00 -0700 | [diff] [blame] | 2530 |     if (ret < 0) | 
 | 2531 |     { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2532 |         BMCWEB_LOG_ERROR("Failed to read MESSAGE field: {}", strerror(-ret)); | 
| Jason M. Bills | e1f2634 | 2018-07-18 12:12:00 -0700 | [diff] [blame] | 2533 |         return 1; | 
 | 2534 |     } | 
| Jason M. Bills | a8fe54f | 2020-11-20 15:57:55 -0800 | [diff] [blame] | 2535 |     message += std::string(msg); | 
| Jason M. Bills | e1f2634 | 2018-07-18 12:12:00 -0700 | [diff] [blame] | 2536 |  | 
 | 2537 |     // Get the severity from the PRIORITY field | 
| Ed Tanous | 271584a | 2019-07-09 16:24:22 -0700 | [diff] [blame] | 2538 |     long int severity = 8; // Default to an invalid priority | 
| Jason M. Bills | 16428a1 | 2018-11-02 12:42:29 -0700 | [diff] [blame] | 2539 |     ret = getJournalMetadata(journal, "PRIORITY", 10, severity); | 
| Jason M. Bills | e1f2634 | 2018-07-18 12:12:00 -0700 | [diff] [blame] | 2540 |     if (ret < 0) | 
 | 2541 |     { | 
| Carson Labrado | bf2dded | 2023-08-10 00:37:06 +0000 | [diff] [blame] | 2542 |         BMCWEB_LOG_DEBUG("Failed to read PRIORITY field: {}", strerror(-ret)); | 
| Jason M. Bills | e1f2634 | 2018-07-18 12:12:00 -0700 | [diff] [blame] | 2543 |     } | 
| Jason M. Bills | e1f2634 | 2018-07-18 12:12:00 -0700 | [diff] [blame] | 2544 |  | 
 | 2545 |     // Get the Created time from the timestamp | 
| Jason M. Bills | 16428a1 | 2018-11-02 12:42:29 -0700 | [diff] [blame] | 2546 |     std::string entryTimeStr; | 
 | 2547 |     if (!getEntryTimestamp(journal, entryTimeStr)) | 
| Jason M. Bills | e1f2634 | 2018-07-18 12:12:00 -0700 | [diff] [blame] | 2548 |     { | 
| Jason M. Bills | 16428a1 | 2018-11-02 12:42:29 -0700 | [diff] [blame] | 2549 |         return 1; | 
| Jason M. Bills | e1f2634 | 2018-07-18 12:12:00 -0700 | [diff] [blame] | 2550 |     } | 
| Jason M. Bills | e1f2634 | 2018-07-18 12:12:00 -0700 | [diff] [blame] | 2551 |  | 
 | 2552 |     // Fill in the log entry with the gathered data | 
| Vijay Lobo | 9c11a17 | 2021-10-07 16:53:16 -0500 | [diff] [blame] | 2553 |     bmcJournalLogEntryJson["@odata.type"] = "#LogEntry.v1_9_0.LogEntry"; | 
| Ed Tanous | ef4c65b | 2023-04-24 15:28:50 -0700 | [diff] [blame] | 2554 |     bmcJournalLogEntryJson["@odata.id"] = boost::urls::format( | 
 | 2555 |         "/redfish/v1/Managers/bmc/LogServices/Journal/Entries/{}", | 
| Willy Tu | eddfc43 | 2022-09-26 16:46:38 +0000 | [diff] [blame] | 2556 |         bmcJournalLogEntryID); | 
| Jason M. Bills | 84afc48 | 2022-06-24 12:38:23 -0700 | [diff] [blame] | 2557 |     bmcJournalLogEntryJson["Name"] = "BMC Journal Entry"; | 
 | 2558 |     bmcJournalLogEntryJson["Id"] = bmcJournalLogEntryID; | 
 | 2559 |     bmcJournalLogEntryJson["Message"] = std::move(message); | 
 | 2560 |     bmcJournalLogEntryJson["EntryType"] = "Oem"; | 
 | 2561 |     bmcJournalLogEntryJson["Severity"] = severity <= 2   ? "Critical" | 
 | 2562 |                                          : severity <= 4 ? "Warning" | 
 | 2563 |                                                          : "OK"; | 
 | 2564 |     bmcJournalLogEntryJson["OemRecordFormat"] = "BMC Journal Entry"; | 
 | 2565 |     bmcJournalLogEntryJson["Created"] = std::move(entryTimeStr); | 
| Jason M. Bills | e1f2634 | 2018-07-18 12:12:00 -0700 | [diff] [blame] | 2566 |     return 0; | 
 | 2567 | } | 
 | 2568 |  | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 2569 | inline void requestRoutesBMCJournalLogEntryCollection(App& app) | 
| Jason M. Bills | e1f2634 | 2018-07-18 12:12:00 -0700 | [diff] [blame] | 2570 | { | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 2571 |     BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/LogServices/Journal/Entries/") | 
| Ed Tanous | ed39821 | 2021-06-09 17:05:54 -0700 | [diff] [blame] | 2572 |         .privileges(redfish::privileges::getLogEntryCollection) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2573 |         .methods(boost::beast::http::verb::get)( | 
 | 2574 |             [&app](const crow::Request& req, | 
 | 2575 |                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { | 
 | 2576 |         query_param::QueryCapabilities capabilities = { | 
 | 2577 |             .canDelegateTop = true, | 
 | 2578 |             .canDelegateSkip = true, | 
 | 2579 |         }; | 
 | 2580 |         query_param::Query delegatedQuery; | 
 | 2581 |         if (!redfish::setUpRedfishRouteWithDelegation( | 
| Carson Labrado | 3ba0007 | 2022-06-06 19:40:56 +0000 | [diff] [blame] | 2582 |                 app, req, asyncResp, delegatedQuery, capabilities)) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2583 |         { | 
 | 2584 |             return; | 
 | 2585 |         } | 
| Ed Tanous | 3648c8b | 2022-07-25 13:39:59 -0700 | [diff] [blame] | 2586 |  | 
 | 2587 |         size_t skip = delegatedQuery.skip.value_or(0); | 
| Jiaqing Zhao | 5143f7a | 2022-07-22 09:33:33 +0800 | [diff] [blame] | 2588 |         size_t top = delegatedQuery.top.value_or(query_param::Query::maxTop); | 
| Ed Tanous | 3648c8b | 2022-07-25 13:39:59 -0700 | [diff] [blame] | 2589 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2590 |         // Collections don't include the static data added by SubRoute | 
 | 2591 |         // because it has a duplicate entry for members | 
 | 2592 |         asyncResp->res.jsonValue["@odata.type"] = | 
 | 2593 |             "#LogEntryCollection.LogEntryCollection"; | 
 | 2594 |         asyncResp->res.jsonValue["@odata.id"] = | 
 | 2595 |             "/redfish/v1/Managers/bmc/LogServices/Journal/Entries"; | 
 | 2596 |         asyncResp->res.jsonValue["Name"] = "Open BMC Journal Entries"; | 
 | 2597 |         asyncResp->res.jsonValue["Description"] = | 
 | 2598 |             "Collection of BMC Journal Entries"; | 
 | 2599 |         nlohmann::json& logEntryArray = asyncResp->res.jsonValue["Members"]; | 
 | 2600 |         logEntryArray = nlohmann::json::array(); | 
| Jason M. Bills | e1f2634 | 2018-07-18 12:12:00 -0700 | [diff] [blame] | 2601 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2602 |         // Go through the journal and use the timestamp to create a | 
 | 2603 |         // unique ID for each entry | 
 | 2604 |         sd_journal* journalTmp = nullptr; | 
 | 2605 |         int ret = sd_journal_open(&journalTmp, SD_JOURNAL_LOCAL_ONLY); | 
 | 2606 |         if (ret < 0) | 
 | 2607 |         { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2608 |             BMCWEB_LOG_ERROR("failed to open journal: {}", strerror(-ret)); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2609 |             messages::internalError(asyncResp->res); | 
 | 2610 |             return; | 
 | 2611 |         } | 
 | 2612 |         std::unique_ptr<sd_journal, decltype(&sd_journal_close)> journal( | 
 | 2613 |             journalTmp, sd_journal_close); | 
 | 2614 |         journalTmp = nullptr; | 
 | 2615 |         uint64_t entryCount = 0; | 
 | 2616 |         // Reset the unique ID on the first entry | 
 | 2617 |         bool firstEntry = true; | 
 | 2618 |         SD_JOURNAL_FOREACH(journal.get()) | 
 | 2619 |         { | 
 | 2620 |             entryCount++; | 
 | 2621 |             // Handle paging using skip (number of entries to skip from | 
 | 2622 |             // the start) and top (number of entries to display) | 
| Ed Tanous | 3648c8b | 2022-07-25 13:39:59 -0700 | [diff] [blame] | 2623 |             if (entryCount <= skip || entryCount > skip + top) | 
| George Liu | 0fda0f1 | 2021-11-16 10:06:17 +0800 | [diff] [blame] | 2624 |             { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2625 |                 continue; | 
 | 2626 |             } | 
 | 2627 |  | 
 | 2628 |             std::string idStr; | 
 | 2629 |             if (!getUniqueEntryID(journal.get(), idStr, firstEntry)) | 
 | 2630 |             { | 
 | 2631 |                 continue; | 
 | 2632 |             } | 
| Jason M. Bills | efde4ec | 2022-06-24 08:59:52 -0700 | [diff] [blame] | 2633 |             firstEntry = false; | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2634 |  | 
| Jason M. Bills | 3a48b3a | 2022-06-24 10:10:15 -0700 | [diff] [blame] | 2635 |             nlohmann::json::object_t bmcJournalLogEntry; | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2636 |             if (fillBMCJournalLogEntryJson(idStr, journal.get(), | 
 | 2637 |                                            bmcJournalLogEntry) != 0) | 
 | 2638 |             { | 
| George Liu | 0fda0f1 | 2021-11-16 10:06:17 +0800 | [diff] [blame] | 2639 |                 messages::internalError(asyncResp->res); | 
 | 2640 |                 return; | 
 | 2641 |             } | 
| Patrick Williams | b2ba307 | 2023-05-12 10:27:39 -0500 | [diff] [blame] | 2642 |             logEntryArray.emplace_back(std::move(bmcJournalLogEntry)); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2643 |         } | 
 | 2644 |         asyncResp->res.jsonValue["Members@odata.count"] = entryCount; | 
| Ed Tanous | 3648c8b | 2022-07-25 13:39:59 -0700 | [diff] [blame] | 2645 |         if (skip + top < entryCount) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2646 |         { | 
 | 2647 |             asyncResp->res.jsonValue["Members@odata.nextLink"] = | 
 | 2648 |                 "/redfish/v1/Managers/bmc/LogServices/Journal/Entries?$skip=" + | 
| Ed Tanous | 3648c8b | 2022-07-25 13:39:59 -0700 | [diff] [blame] | 2649 |                 std::to_string(skip + top); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2650 |         } | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 2651 |     }); | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 2652 | } | 
| Jason M. Bills | e1f2634 | 2018-07-18 12:12:00 -0700 | [diff] [blame] | 2653 |  | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 2654 | inline void requestRoutesBMCJournalLogEntry(App& app) | 
| Jason M. Bills | e1f2634 | 2018-07-18 12:12:00 -0700 | [diff] [blame] | 2655 | { | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 2656 |     BMCWEB_ROUTE(app, | 
 | 2657 |                  "/redfish/v1/Managers/bmc/LogServices/Journal/Entries/<str>/") | 
| Ed Tanous | ed39821 | 2021-06-09 17:05:54 -0700 | [diff] [blame] | 2658 |         .privileges(redfish::privileges::getLogEntry) | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 2659 |         .methods(boost::beast::http::verb::get)( | 
| Ed Tanous | 45ca1b8 | 2022-03-25 13:07:27 -0700 | [diff] [blame] | 2660 |             [&app](const crow::Request& req, | 
 | 2661 |                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 2662 |                    const std::string& entryID) { | 
| Carson Labrado | 3ba0007 | 2022-06-06 19:40:56 +0000 | [diff] [blame] | 2663 |         if (!redfish::setUpRedfishRoute(app, req, asyncResp)) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2664 |         { | 
 | 2665 |             return; | 
 | 2666 |         } | 
 | 2667 |         // Convert the unique ID back to a timestamp to find the entry | 
 | 2668 |         uint64_t ts = 0; | 
 | 2669 |         uint64_t index = 0; | 
 | 2670 |         if (!getTimestampFromID(asyncResp, entryID, ts, index)) | 
 | 2671 |         { | 
 | 2672 |             return; | 
 | 2673 |         } | 
| Jason M. Bills | e1f2634 | 2018-07-18 12:12:00 -0700 | [diff] [blame] | 2674 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2675 |         sd_journal* journalTmp = nullptr; | 
 | 2676 |         int ret = sd_journal_open(&journalTmp, SD_JOURNAL_LOCAL_ONLY); | 
 | 2677 |         if (ret < 0) | 
 | 2678 |         { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2679 |             BMCWEB_LOG_ERROR("failed to open journal: {}", strerror(-ret)); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2680 |             messages::internalError(asyncResp->res); | 
 | 2681 |             return; | 
 | 2682 |         } | 
 | 2683 |         std::unique_ptr<sd_journal, decltype(&sd_journal_close)> journal( | 
 | 2684 |             journalTmp, sd_journal_close); | 
 | 2685 |         journalTmp = nullptr; | 
 | 2686 |         // Go to the timestamp in the log and move to the entry at the | 
 | 2687 |         // index tracking the unique ID | 
 | 2688 |         std::string idStr; | 
 | 2689 |         bool firstEntry = true; | 
 | 2690 |         ret = sd_journal_seek_realtime_usec(journal.get(), ts); | 
 | 2691 |         if (ret < 0) | 
 | 2692 |         { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2693 |             BMCWEB_LOG_ERROR("failed to seek to an entry in journal{}", | 
 | 2694 |                              strerror(-ret)); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2695 |             messages::internalError(asyncResp->res); | 
 | 2696 |             return; | 
 | 2697 |         } | 
 | 2698 |         for (uint64_t i = 0; i <= index; i++) | 
 | 2699 |         { | 
 | 2700 |             sd_journal_next(journal.get()); | 
 | 2701 |             if (!getUniqueEntryID(journal.get(), idStr, firstEntry)) | 
 | 2702 |             { | 
 | 2703 |                 messages::internalError(asyncResp->res); | 
 | 2704 |                 return; | 
 | 2705 |             } | 
| Jason M. Bills | efde4ec | 2022-06-24 08:59:52 -0700 | [diff] [blame] | 2706 |             firstEntry = false; | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2707 |         } | 
 | 2708 |         // Confirm that the entry ID matches what was requested | 
 | 2709 |         if (idStr != entryID) | 
 | 2710 |         { | 
| Jiaqing Zhao | 9db4ba2 | 2022-10-09 17:24:40 +0800 | [diff] [blame] | 2711 |             messages::resourceNotFound(asyncResp->res, "LogEntry", entryID); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2712 |             return; | 
 | 2713 |         } | 
| zhanghch05 | 8d1b46d | 2021-04-01 11:18:24 +0800 | [diff] [blame] | 2714 |  | 
| Jason M. Bills | 3a48b3a | 2022-06-24 10:10:15 -0700 | [diff] [blame] | 2715 |         nlohmann::json::object_t bmcJournalLogEntry; | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2716 |         if (fillBMCJournalLogEntryJson(entryID, journal.get(), | 
| Jason M. Bills | 3a48b3a | 2022-06-24 10:10:15 -0700 | [diff] [blame] | 2717 |                                        bmcJournalLogEntry) != 0) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2718 |         { | 
 | 2719 |             messages::internalError(asyncResp->res); | 
 | 2720 |             return; | 
 | 2721 |         } | 
| Jason M. Bills | d405bb5 | 2022-06-24 10:52:05 -0700 | [diff] [blame] | 2722 |         asyncResp->res.jsonValue.update(bmcJournalLogEntry); | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 2723 |     }); | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 2724 | } | 
 | 2725 |  | 
| Claire Weinan | fdd2690 | 2022-03-01 14:18:25 -0800 | [diff] [blame] | 2726 | inline void | 
 | 2727 |     getDumpServiceInfo(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 2728 |                        const std::string& dumpType) | 
 | 2729 | { | 
 | 2730 |     std::string dumpPath; | 
 | 2731 |     std::string overWritePolicy; | 
 | 2732 |     bool collectDiagnosticDataSupported = false; | 
 | 2733 |  | 
 | 2734 |     if (dumpType == "BMC") | 
 | 2735 |     { | 
 | 2736 |         dumpPath = "/redfish/v1/Managers/bmc/LogServices/Dump"; | 
 | 2737 |         overWritePolicy = "WrapsWhenFull"; | 
 | 2738 |         collectDiagnosticDataSupported = true; | 
 | 2739 |     } | 
 | 2740 |     else if (dumpType == "FaultLog") | 
 | 2741 |     { | 
 | 2742 |         dumpPath = "/redfish/v1/Managers/bmc/LogServices/FaultLog"; | 
 | 2743 |         overWritePolicy = "Unknown"; | 
 | 2744 |         collectDiagnosticDataSupported = false; | 
 | 2745 |     } | 
 | 2746 |     else if (dumpType == "System") | 
 | 2747 |     { | 
 | 2748 |         dumpPath = "/redfish/v1/Systems/system/LogServices/Dump"; | 
 | 2749 |         overWritePolicy = "WrapsWhenFull"; | 
 | 2750 |         collectDiagnosticDataSupported = true; | 
 | 2751 |     } | 
 | 2752 |     else | 
 | 2753 |     { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2754 |         BMCWEB_LOG_ERROR("getDumpServiceInfo() invalid dump type: {}", | 
 | 2755 |                          dumpType); | 
| Claire Weinan | fdd2690 | 2022-03-01 14:18:25 -0800 | [diff] [blame] | 2756 |         messages::internalError(asyncResp->res); | 
 | 2757 |         return; | 
 | 2758 |     } | 
 | 2759 |  | 
 | 2760 |     asyncResp->res.jsonValue["@odata.id"] = dumpPath; | 
 | 2761 |     asyncResp->res.jsonValue["@odata.type"] = "#LogService.v1_2_0.LogService"; | 
 | 2762 |     asyncResp->res.jsonValue["Name"] = "Dump LogService"; | 
 | 2763 |     asyncResp->res.jsonValue["Description"] = dumpType + " Dump LogService"; | 
 | 2764 |     asyncResp->res.jsonValue["Id"] = std::filesystem::path(dumpPath).filename(); | 
 | 2765 |     asyncResp->res.jsonValue["OverWritePolicy"] = std::move(overWritePolicy); | 
 | 2766 |  | 
 | 2767 |     std::pair<std::string, std::string> redfishDateTimeOffset = | 
| Ed Tanous | 2b82937 | 2022-08-03 14:22:34 -0700 | [diff] [blame] | 2768 |         redfish::time_utils::getDateTimeOffsetNow(); | 
| Claire Weinan | fdd2690 | 2022-03-01 14:18:25 -0800 | [diff] [blame] | 2769 |     asyncResp->res.jsonValue["DateTime"] = redfishDateTimeOffset.first; | 
 | 2770 |     asyncResp->res.jsonValue["DateTimeLocalOffset"] = | 
 | 2771 |         redfishDateTimeOffset.second; | 
 | 2772 |  | 
 | 2773 |     asyncResp->res.jsonValue["Entries"]["@odata.id"] = dumpPath + "/Entries"; | 
| Claire Weinan | fdd2690 | 2022-03-01 14:18:25 -0800 | [diff] [blame] | 2774 |  | 
 | 2775 |     if (collectDiagnosticDataSupported) | 
 | 2776 |     { | 
 | 2777 |         asyncResp->res.jsonValue["Actions"]["#LogService.CollectDiagnosticData"] | 
 | 2778 |                                 ["target"] = | 
 | 2779 |             dumpPath + "/Actions/LogService.CollectDiagnosticData"; | 
 | 2780 |     } | 
| Claire Weinan | 0d94621 | 2022-07-13 19:40:19 -0700 | [diff] [blame] | 2781 |  | 
 | 2782 |     constexpr std::array<std::string_view, 1> interfaces = {deleteAllInterface}; | 
 | 2783 |     dbus::utility::getSubTreePaths( | 
 | 2784 |         "/xyz/openbmc_project/dump", 0, interfaces, | 
 | 2785 |         [asyncResp, dumpType, dumpPath]( | 
 | 2786 |             const boost::system::error_code& ec, | 
 | 2787 |             const dbus::utility::MapperGetSubTreePathsResponse& subTreePaths) { | 
 | 2788 |         if (ec) | 
 | 2789 |         { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2790 |             BMCWEB_LOG_ERROR("getDumpServiceInfo respHandler got error {}", ec); | 
| Claire Weinan | 0d94621 | 2022-07-13 19:40:19 -0700 | [diff] [blame] | 2791 |             // Assume that getting an error simply means there are no dump | 
 | 2792 |             // LogServices. Return without adding any error response. | 
 | 2793 |             return; | 
 | 2794 |         } | 
 | 2795 |  | 
 | 2796 |         const std::string dbusDumpPath = | 
 | 2797 |             "/xyz/openbmc_project/dump/" + | 
 | 2798 |             boost::algorithm::to_lower_copy(dumpType); | 
 | 2799 |  | 
 | 2800 |         for (const std::string& path : subTreePaths) | 
 | 2801 |         { | 
 | 2802 |             if (path == dbusDumpPath) | 
 | 2803 |             { | 
 | 2804 |                 asyncResp->res | 
 | 2805 |                     .jsonValue["Actions"]["#LogService.ClearLog"]["target"] = | 
 | 2806 |                     dumpPath + "/Actions/LogService.ClearLog"; | 
 | 2807 |                 break; | 
 | 2808 |             } | 
 | 2809 |         } | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 2810 |     }); | 
| Claire Weinan | fdd2690 | 2022-03-01 14:18:25 -0800 | [diff] [blame] | 2811 | } | 
 | 2812 |  | 
 | 2813 | inline void handleLogServicesDumpServiceGet( | 
 | 2814 |     crow::App& app, const std::string& dumpType, const crow::Request& req, | 
 | 2815 |     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) | 
 | 2816 | { | 
 | 2817 |     if (!redfish::setUpRedfishRoute(app, req, asyncResp)) | 
 | 2818 |     { | 
 | 2819 |         return; | 
 | 2820 |     } | 
 | 2821 |     getDumpServiceInfo(asyncResp, dumpType); | 
 | 2822 | } | 
 | 2823 |  | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 2824 | inline void handleLogServicesDumpServiceComputerSystemGet( | 
 | 2825 |     crow::App& app, const crow::Request& req, | 
 | 2826 |     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 2827 |     const std::string& chassisId) | 
 | 2828 | { | 
 | 2829 |     if (!redfish::setUpRedfishRoute(app, req, asyncResp)) | 
 | 2830 |     { | 
 | 2831 |         return; | 
 | 2832 |     } | 
 | 2833 |     if (chassisId != "system") | 
 | 2834 |     { | 
 | 2835 |         messages::resourceNotFound(asyncResp->res, "ComputerSystem", chassisId); | 
 | 2836 |         return; | 
 | 2837 |     } | 
 | 2838 |     getDumpServiceInfo(asyncResp, "System"); | 
 | 2839 | } | 
 | 2840 |  | 
| Claire Weinan | fdd2690 | 2022-03-01 14:18:25 -0800 | [diff] [blame] | 2841 | inline void handleLogServicesDumpEntriesCollectionGet( | 
 | 2842 |     crow::App& app, const std::string& dumpType, const crow::Request& req, | 
 | 2843 |     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) | 
 | 2844 | { | 
 | 2845 |     if (!redfish::setUpRedfishRoute(app, req, asyncResp)) | 
 | 2846 |     { | 
 | 2847 |         return; | 
 | 2848 |     } | 
 | 2849 |     getDumpEntryCollection(asyncResp, dumpType); | 
 | 2850 | } | 
 | 2851 |  | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 2852 | inline void handleLogServicesDumpEntriesCollectionComputerSystemGet( | 
 | 2853 |     crow::App& app, const crow::Request& req, | 
 | 2854 |     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 2855 |     const std::string& chassisId) | 
 | 2856 | { | 
 | 2857 |     if (!redfish::setUpRedfishRoute(app, req, asyncResp)) | 
 | 2858 |     { | 
 | 2859 |         return; | 
 | 2860 |     } | 
 | 2861 |     if (chassisId != "system") | 
 | 2862 |     { | 
 | 2863 |         messages::resourceNotFound(asyncResp->res, "ComputerSystem", chassisId); | 
 | 2864 |         return; | 
 | 2865 |     } | 
 | 2866 |     getDumpEntryCollection(asyncResp, "System"); | 
 | 2867 | } | 
 | 2868 |  | 
| Claire Weinan | fdd2690 | 2022-03-01 14:18:25 -0800 | [diff] [blame] | 2869 | inline void handleLogServicesDumpEntryGet( | 
 | 2870 |     crow::App& app, const std::string& dumpType, const crow::Request& req, | 
 | 2871 |     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 2872 |     const std::string& dumpId) | 
 | 2873 | { | 
 | 2874 |     if (!redfish::setUpRedfishRoute(app, req, asyncResp)) | 
 | 2875 |     { | 
 | 2876 |         return; | 
 | 2877 |     } | 
 | 2878 |     getDumpEntryById(asyncResp, dumpId, dumpType); | 
 | 2879 | } | 
| Carson Labrado | 168d1b1 | 2023-03-27 17:04:46 +0000 | [diff] [blame] | 2880 |  | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 2881 | inline void handleLogServicesDumpEntryComputerSystemGet( | 
 | 2882 |     crow::App& app, const crow::Request& req, | 
 | 2883 |     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 2884 |     const std::string& chassisId, const std::string& dumpId) | 
 | 2885 | { | 
 | 2886 |     if (!redfish::setUpRedfishRoute(app, req, asyncResp)) | 
 | 2887 |     { | 
 | 2888 |         return; | 
 | 2889 |     } | 
 | 2890 |     if (chassisId != "system") | 
 | 2891 |     { | 
 | 2892 |         messages::resourceNotFound(asyncResp->res, "ComputerSystem", chassisId); | 
 | 2893 |         return; | 
 | 2894 |     } | 
 | 2895 |     getDumpEntryById(asyncResp, dumpId, "System"); | 
 | 2896 | } | 
| Claire Weinan | fdd2690 | 2022-03-01 14:18:25 -0800 | [diff] [blame] | 2897 |  | 
 | 2898 | inline void handleLogServicesDumpEntryDelete( | 
 | 2899 |     crow::App& app, const std::string& dumpType, const crow::Request& req, | 
 | 2900 |     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 2901 |     const std::string& dumpId) | 
 | 2902 | { | 
 | 2903 |     if (!redfish::setUpRedfishRoute(app, req, asyncResp)) | 
 | 2904 |     { | 
 | 2905 |         return; | 
 | 2906 |     } | 
 | 2907 |     deleteDumpEntry(asyncResp, dumpId, dumpType); | 
 | 2908 | } | 
 | 2909 |  | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 2910 | inline void handleLogServicesDumpEntryComputerSystemDelete( | 
 | 2911 |     crow::App& app, const crow::Request& req, | 
 | 2912 |     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 2913 |     const std::string& chassisId, const std::string& dumpId) | 
 | 2914 | { | 
 | 2915 |     if (!redfish::setUpRedfishRoute(app, req, asyncResp)) | 
 | 2916 |     { | 
 | 2917 |         return; | 
 | 2918 |     } | 
 | 2919 |     if (chassisId != "system") | 
 | 2920 |     { | 
 | 2921 |         messages::resourceNotFound(asyncResp->res, "ComputerSystem", chassisId); | 
 | 2922 |         return; | 
 | 2923 |     } | 
 | 2924 |     deleteDumpEntry(asyncResp, dumpId, "System"); | 
 | 2925 | } | 
 | 2926 |  | 
| Carson Labrado | 168d1b1 | 2023-03-27 17:04:46 +0000 | [diff] [blame] | 2927 | inline void handleLogServicesDumpEntryDownloadGet( | 
 | 2928 |     crow::App& app, const std::string& dumpType, const crow::Request& req, | 
 | 2929 |     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 2930 |     const std::string& dumpId) | 
 | 2931 | { | 
 | 2932 |     if (!redfish::setUpRedfishRoute(app, req, asyncResp)) | 
 | 2933 |     { | 
 | 2934 |         return; | 
 | 2935 |     } | 
 | 2936 |     downloadDumpEntry(asyncResp, dumpId, dumpType); | 
 | 2937 | } | 
 | 2938 |  | 
 | 2939 | inline void handleDBusEventLogEntryDownloadGet( | 
 | 2940 |     crow::App& app, const std::string& dumpType, const crow::Request& req, | 
 | 2941 |     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 2942 |     const std::string& systemName, const std::string& entryID) | 
 | 2943 | { | 
 | 2944 |     if (!redfish::setUpRedfishRoute(app, req, asyncResp)) | 
 | 2945 |     { | 
 | 2946 |         return; | 
 | 2947 |     } | 
 | 2948 |     if (!http_helpers::isContentTypeAllowed( | 
 | 2949 |             req.getHeaderValue("Accept"), | 
 | 2950 |             http_helpers::ContentType::OctetStream, true)) | 
 | 2951 |     { | 
 | 2952 |         asyncResp->res.result(boost::beast::http::status::bad_request); | 
 | 2953 |         return; | 
 | 2954 |     } | 
 | 2955 |     downloadEventLogEntry(asyncResp, systemName, entryID, dumpType); | 
 | 2956 | } | 
 | 2957 |  | 
| Claire Weinan | fdd2690 | 2022-03-01 14:18:25 -0800 | [diff] [blame] | 2958 | inline void handleLogServicesDumpCollectDiagnosticDataPost( | 
 | 2959 |     crow::App& app, const std::string& dumpType, const crow::Request& req, | 
 | 2960 |     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) | 
 | 2961 | { | 
 | 2962 |     if (!redfish::setUpRedfishRoute(app, req, asyncResp)) | 
 | 2963 |     { | 
 | 2964 |         return; | 
 | 2965 |     } | 
 | 2966 |     createDump(asyncResp, req, dumpType); | 
 | 2967 | } | 
 | 2968 |  | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 2969 | inline void handleLogServicesDumpCollectDiagnosticDataComputerSystemPost( | 
 | 2970 |     crow::App& app, const crow::Request& req, | 
 | 2971 |     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
| Ed Tanous | 7f3e84a | 2022-12-28 16:22:54 -0800 | [diff] [blame] | 2972 |     const std::string& systemName) | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 2973 | { | 
 | 2974 |     if (!redfish::setUpRedfishRoute(app, req, asyncResp)) | 
 | 2975 |     { | 
 | 2976 |         return; | 
 | 2977 |     } | 
| Ed Tanous | 7f3e84a | 2022-12-28 16:22:54 -0800 | [diff] [blame] | 2978 |  | 
 | 2979 |     if constexpr (bmcwebEnableMultiHost) | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 2980 |     { | 
| Ed Tanous | 7f3e84a | 2022-12-28 16:22:54 -0800 | [diff] [blame] | 2981 |         // Option currently returns no systems.  TBD | 
 | 2982 |         messages::resourceNotFound(asyncResp->res, "ComputerSystem", | 
 | 2983 |                                    systemName); | 
 | 2984 |         return; | 
 | 2985 |     } | 
 | 2986 |     if (systemName != "system") | 
 | 2987 |     { | 
 | 2988 |         messages::resourceNotFound(asyncResp->res, "ComputerSystem", | 
 | 2989 |                                    systemName); | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 2990 |         return; | 
 | 2991 |     } | 
 | 2992 |     createDump(asyncResp, req, "System"); | 
 | 2993 | } | 
 | 2994 |  | 
| Claire Weinan | fdd2690 | 2022-03-01 14:18:25 -0800 | [diff] [blame] | 2995 | inline void handleLogServicesDumpClearLogPost( | 
 | 2996 |     crow::App& app, const std::string& dumpType, const crow::Request& req, | 
 | 2997 |     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) | 
 | 2998 | { | 
 | 2999 |     if (!redfish::setUpRedfishRoute(app, req, asyncResp)) | 
 | 3000 |     { | 
 | 3001 |         return; | 
 | 3002 |     } | 
 | 3003 |     clearDump(asyncResp, dumpType); | 
 | 3004 | } | 
 | 3005 |  | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 3006 | inline void handleLogServicesDumpClearLogComputerSystemPost( | 
 | 3007 |     crow::App& app, const crow::Request& req, | 
 | 3008 |     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
| Ed Tanous | 7f3e84a | 2022-12-28 16:22:54 -0800 | [diff] [blame] | 3009 |     const std::string& systemName) | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 3010 | { | 
 | 3011 |     if (!redfish::setUpRedfishRoute(app, req, asyncResp)) | 
 | 3012 |     { | 
 | 3013 |         return; | 
 | 3014 |     } | 
| Ed Tanous | 7f3e84a | 2022-12-28 16:22:54 -0800 | [diff] [blame] | 3015 |     if constexpr (bmcwebEnableMultiHost) | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 3016 |     { | 
| Ed Tanous | 7f3e84a | 2022-12-28 16:22:54 -0800 | [diff] [blame] | 3017 |         // Option currently returns no systems.  TBD | 
 | 3018 |         messages::resourceNotFound(asyncResp->res, "ComputerSystem", | 
 | 3019 |                                    systemName); | 
 | 3020 |         return; | 
 | 3021 |     } | 
 | 3022 |     if (systemName != "system") | 
 | 3023 |     { | 
 | 3024 |         messages::resourceNotFound(asyncResp->res, "ComputerSystem", | 
 | 3025 |                                    systemName); | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 3026 |         return; | 
 | 3027 |     } | 
 | 3028 |     clearDump(asyncResp, "System"); | 
 | 3029 | } | 
 | 3030 |  | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 3031 | inline void requestRoutesBMCDumpService(App& app) | 
 | 3032 | { | 
 | 3033 |     BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/LogServices/Dump/") | 
| Ed Tanous | ed39821 | 2021-06-09 17:05:54 -0700 | [diff] [blame] | 3034 |         .privileges(redfish::privileges::getLogService) | 
| Claire Weinan | fdd2690 | 2022-03-01 14:18:25 -0800 | [diff] [blame] | 3035 |         .methods(boost::beast::http::verb::get)(std::bind_front( | 
 | 3036 |             handleLogServicesDumpServiceGet, std::ref(app), "BMC")); | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 3037 | } | 
 | 3038 |  | 
 | 3039 | inline void requestRoutesBMCDumpEntryCollection(App& app) | 
 | 3040 | { | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 3041 |     BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/LogServices/Dump/Entries/") | 
| Ed Tanous | ed39821 | 2021-06-09 17:05:54 -0700 | [diff] [blame] | 3042 |         .privileges(redfish::privileges::getLogEntryCollection) | 
| Claire Weinan | fdd2690 | 2022-03-01 14:18:25 -0800 | [diff] [blame] | 3043 |         .methods(boost::beast::http::verb::get)(std::bind_front( | 
 | 3044 |             handleLogServicesDumpEntriesCollectionGet, std::ref(app), "BMC")); | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 3045 | } | 
 | 3046 |  | 
 | 3047 | inline void requestRoutesBMCDumpEntry(App& app) | 
 | 3048 | { | 
 | 3049 |     BMCWEB_ROUTE(app, | 
 | 3050 |                  "/redfish/v1/Managers/bmc/LogServices/Dump/Entries/<str>/") | 
| Ed Tanous | ed39821 | 2021-06-09 17:05:54 -0700 | [diff] [blame] | 3051 |         .privileges(redfish::privileges::getLogEntry) | 
| Claire Weinan | fdd2690 | 2022-03-01 14:18:25 -0800 | [diff] [blame] | 3052 |         .methods(boost::beast::http::verb::get)(std::bind_front( | 
 | 3053 |             handleLogServicesDumpEntryGet, std::ref(app), "BMC")); | 
 | 3054 |  | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 3055 |     BMCWEB_ROUTE(app, | 
 | 3056 |                  "/redfish/v1/Managers/bmc/LogServices/Dump/Entries/<str>/") | 
| Ed Tanous | ed39821 | 2021-06-09 17:05:54 -0700 | [diff] [blame] | 3057 |         .privileges(redfish::privileges::deleteLogEntry) | 
| Claire Weinan | fdd2690 | 2022-03-01 14:18:25 -0800 | [diff] [blame] | 3058 |         .methods(boost::beast::http::verb::delete_)(std::bind_front( | 
 | 3059 |             handleLogServicesDumpEntryDelete, std::ref(app), "BMC")); | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 3060 | } | 
 | 3061 |  | 
| Carson Labrado | 168d1b1 | 2023-03-27 17:04:46 +0000 | [diff] [blame] | 3062 | inline void requestRoutesBMCDumpEntryDownload(App& app) | 
 | 3063 | { | 
 | 3064 |     BMCWEB_ROUTE( | 
 | 3065 |         app, | 
| Ravi Teja | 9e9d99d | 2023-11-08 05:33:59 -0600 | [diff] [blame^] | 3066 |         "/redfish/v1/Managers/bmc/LogServices/Dump/Entries/<str>/attachment/") | 
| Carson Labrado | 168d1b1 | 2023-03-27 17:04:46 +0000 | [diff] [blame] | 3067 |         .privileges(redfish::privileges::getLogEntry) | 
 | 3068 |         .methods(boost::beast::http::verb::get)(std::bind_front( | 
 | 3069 |             handleLogServicesDumpEntryDownloadGet, std::ref(app), "BMC")); | 
 | 3070 | } | 
 | 3071 |  | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 3072 | inline void requestRoutesBMCDumpCreate(App& app) | 
 | 3073 | { | 
| George Liu | 0fda0f1 | 2021-11-16 10:06:17 +0800 | [diff] [blame] | 3074 |     BMCWEB_ROUTE( | 
 | 3075 |         app, | 
 | 3076 |         "/redfish/v1/Managers/bmc/LogServices/Dump/Actions/LogService.CollectDiagnosticData/") | 
| Ed Tanous | ed39821 | 2021-06-09 17:05:54 -0700 | [diff] [blame] | 3077 |         .privileges(redfish::privileges::postLogService) | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 3078 |         .methods(boost::beast::http::verb::post)( | 
| Claire Weinan | fdd2690 | 2022-03-01 14:18:25 -0800 | [diff] [blame] | 3079 |             std::bind_front(handleLogServicesDumpCollectDiagnosticDataPost, | 
 | 3080 |                             std::ref(app), "BMC")); | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 3081 | } | 
 | 3082 |  | 
 | 3083 | inline void requestRoutesBMCDumpClear(App& app) | 
 | 3084 | { | 
| George Liu | 0fda0f1 | 2021-11-16 10:06:17 +0800 | [diff] [blame] | 3085 |     BMCWEB_ROUTE( | 
 | 3086 |         app, | 
 | 3087 |         "/redfish/v1/Managers/bmc/LogServices/Dump/Actions/LogService.ClearLog/") | 
| Ed Tanous | ed39821 | 2021-06-09 17:05:54 -0700 | [diff] [blame] | 3088 |         .privileges(redfish::privileges::postLogService) | 
| Claire Weinan | fdd2690 | 2022-03-01 14:18:25 -0800 | [diff] [blame] | 3089 |         .methods(boost::beast::http::verb::post)(std::bind_front( | 
 | 3090 |             handleLogServicesDumpClearLogPost, std::ref(app), "BMC")); | 
 | 3091 | } | 
 | 3092 |  | 
| Carson Labrado | 168d1b1 | 2023-03-27 17:04:46 +0000 | [diff] [blame] | 3093 | inline void requestRoutesDBusEventLogEntryDownload(App& app) | 
 | 3094 | { | 
 | 3095 |     BMCWEB_ROUTE( | 
 | 3096 |         app, | 
| Ravi Teja | 9e9d99d | 2023-11-08 05:33:59 -0600 | [diff] [blame^] | 3097 |         "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/<str>/attachment/") | 
| Carson Labrado | 168d1b1 | 2023-03-27 17:04:46 +0000 | [diff] [blame] | 3098 |         .privileges(redfish::privileges::getLogEntry) | 
 | 3099 |         .methods(boost::beast::http::verb::get)(std::bind_front( | 
 | 3100 |             handleDBusEventLogEntryDownloadGet, std::ref(app), "System")); | 
 | 3101 | } | 
 | 3102 |  | 
| Claire Weinan | fdd2690 | 2022-03-01 14:18:25 -0800 | [diff] [blame] | 3103 | inline void requestRoutesFaultLogDumpService(App& app) | 
 | 3104 | { | 
 | 3105 |     BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/LogServices/FaultLog/") | 
 | 3106 |         .privileges(redfish::privileges::getLogService) | 
 | 3107 |         .methods(boost::beast::http::verb::get)(std::bind_front( | 
 | 3108 |             handleLogServicesDumpServiceGet, std::ref(app), "FaultLog")); | 
 | 3109 | } | 
 | 3110 |  | 
 | 3111 | inline void requestRoutesFaultLogDumpEntryCollection(App& app) | 
 | 3112 | { | 
 | 3113 |     BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/LogServices/FaultLog/Entries/") | 
 | 3114 |         .privileges(redfish::privileges::getLogEntryCollection) | 
 | 3115 |         .methods(boost::beast::http::verb::get)( | 
 | 3116 |             std::bind_front(handleLogServicesDumpEntriesCollectionGet, | 
 | 3117 |                             std::ref(app), "FaultLog")); | 
 | 3118 | } | 
 | 3119 |  | 
 | 3120 | inline void requestRoutesFaultLogDumpEntry(App& app) | 
 | 3121 | { | 
 | 3122 |     BMCWEB_ROUTE(app, | 
 | 3123 |                  "/redfish/v1/Managers/bmc/LogServices/FaultLog/Entries/<str>/") | 
 | 3124 |         .privileges(redfish::privileges::getLogEntry) | 
 | 3125 |         .methods(boost::beast::http::verb::get)(std::bind_front( | 
 | 3126 |             handleLogServicesDumpEntryGet, std::ref(app), "FaultLog")); | 
 | 3127 |  | 
 | 3128 |     BMCWEB_ROUTE(app, | 
 | 3129 |                  "/redfish/v1/Managers/bmc/LogServices/FaultLog/Entries/<str>/") | 
 | 3130 |         .privileges(redfish::privileges::deleteLogEntry) | 
 | 3131 |         .methods(boost::beast::http::verb::delete_)(std::bind_front( | 
 | 3132 |             handleLogServicesDumpEntryDelete, std::ref(app), "FaultLog")); | 
 | 3133 | } | 
 | 3134 |  | 
 | 3135 | inline void requestRoutesFaultLogDumpClear(App& app) | 
 | 3136 | { | 
 | 3137 |     BMCWEB_ROUTE( | 
 | 3138 |         app, | 
 | 3139 |         "/redfish/v1/Managers/bmc/LogServices/FaultLog/Actions/LogService.ClearLog/") | 
 | 3140 |         .privileges(redfish::privileges::postLogService) | 
 | 3141 |         .methods(boost::beast::http::verb::post)(std::bind_front( | 
 | 3142 |             handleLogServicesDumpClearLogPost, std::ref(app), "FaultLog")); | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 3143 | } | 
 | 3144 |  | 
 | 3145 | inline void requestRoutesSystemDumpService(App& app) | 
 | 3146 | { | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 3147 |     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/Dump/") | 
| Ed Tanous | ed39821 | 2021-06-09 17:05:54 -0700 | [diff] [blame] | 3148 |         .privileges(redfish::privileges::getLogService) | 
| Claire Weinan | 6ab9ad5 | 2022-08-12 18:20:17 -0700 | [diff] [blame] | 3149 |         .methods(boost::beast::http::verb::get)(std::bind_front( | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 3150 |             handleLogServicesDumpServiceComputerSystemGet, std::ref(app))); | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 3151 | } | 
 | 3152 |  | 
 | 3153 | inline void requestRoutesSystemDumpEntryCollection(App& app) | 
 | 3154 | { | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 3155 |     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/Dump/Entries/") | 
| Ed Tanous | ed39821 | 2021-06-09 17:05:54 -0700 | [diff] [blame] | 3156 |         .privileges(redfish::privileges::getLogEntryCollection) | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 3157 |         .methods(boost::beast::http::verb::get)(std::bind_front( | 
 | 3158 |             handleLogServicesDumpEntriesCollectionComputerSystemGet, | 
 | 3159 |             std::ref(app))); | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 3160 | } | 
 | 3161 |  | 
 | 3162 | inline void requestRoutesSystemDumpEntry(App& app) | 
 | 3163 | { | 
 | 3164 |     BMCWEB_ROUTE(app, | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 3165 |                  "/redfish/v1/Systems/<str>/LogServices/Dump/Entries/<str>/") | 
| Ed Tanous | ed39821 | 2021-06-09 17:05:54 -0700 | [diff] [blame] | 3166 |         .privileges(redfish::privileges::getLogEntry) | 
| Claire Weinan | 6ab9ad5 | 2022-08-12 18:20:17 -0700 | [diff] [blame] | 3167 |         .methods(boost::beast::http::verb::get)(std::bind_front( | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 3168 |             handleLogServicesDumpEntryComputerSystemGet, std::ref(app))); | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 3169 |  | 
 | 3170 |     BMCWEB_ROUTE(app, | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 3171 |                  "/redfish/v1/Systems/<str>/LogServices/Dump/Entries/<str>/") | 
| Ed Tanous | ed39821 | 2021-06-09 17:05:54 -0700 | [diff] [blame] | 3172 |         .privileges(redfish::privileges::deleteLogEntry) | 
| Claire Weinan | 6ab9ad5 | 2022-08-12 18:20:17 -0700 | [diff] [blame] | 3173 |         .methods(boost::beast::http::verb::delete_)(std::bind_front( | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 3174 |             handleLogServicesDumpEntryComputerSystemDelete, std::ref(app))); | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 3175 | } | 
 | 3176 |  | 
 | 3177 | inline void requestRoutesSystemDumpCreate(App& app) | 
 | 3178 | { | 
| George Liu | 0fda0f1 | 2021-11-16 10:06:17 +0800 | [diff] [blame] | 3179 |     BMCWEB_ROUTE( | 
 | 3180 |         app, | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 3181 |         "/redfish/v1/Systems/<str>/LogServices/Dump/Actions/LogService.CollectDiagnosticData/") | 
| Ed Tanous | ed39821 | 2021-06-09 17:05:54 -0700 | [diff] [blame] | 3182 |         .privileges(redfish::privileges::postLogService) | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 3183 |         .methods(boost::beast::http::verb::post)(std::bind_front( | 
 | 3184 |             handleLogServicesDumpCollectDiagnosticDataComputerSystemPost, | 
 | 3185 |             std::ref(app))); | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 3186 | } | 
 | 3187 |  | 
 | 3188 | inline void requestRoutesSystemDumpClear(App& app) | 
 | 3189 | { | 
| George Liu | 0fda0f1 | 2021-11-16 10:06:17 +0800 | [diff] [blame] | 3190 |     BMCWEB_ROUTE( | 
 | 3191 |         app, | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 3192 |         "/redfish/v1/Systems/<str>/LogServices/Dump/Actions/LogService.ClearLog/") | 
| Ed Tanous | ed39821 | 2021-06-09 17:05:54 -0700 | [diff] [blame] | 3193 |         .privileges(redfish::privileges::postLogService) | 
| Claire Weinan | 6ab9ad5 | 2022-08-12 18:20:17 -0700 | [diff] [blame] | 3194 |         .methods(boost::beast::http::verb::post)(std::bind_front( | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 3195 |             handleLogServicesDumpClearLogComputerSystemPost, std::ref(app))); | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 3196 | } | 
 | 3197 |  | 
 | 3198 | inline void requestRoutesCrashdumpService(App& app) | 
 | 3199 | { | 
 | 3200 |     // Note: Deviated from redfish privilege registry for GET & HEAD | 
 | 3201 |     // method for security reasons. | 
 | 3202 |     /** | 
 | 3203 |      * Functions triggers appropriate requests on DBus | 
 | 3204 |      */ | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 3205 |     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/Crashdump/") | 
| Ed Tanous | ed39821 | 2021-06-09 17:05:54 -0700 | [diff] [blame] | 3206 |         // This is incorrect, should be: | 
 | 3207 |         //.privileges(redfish::privileges::getLogService) | 
| Ed Tanous | 432a890 | 2021-06-14 15:28:56 -0700 | [diff] [blame] | 3208 |         .privileges({{"ConfigureManager"}}) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3209 |         .methods(boost::beast::http::verb::get)( | 
 | 3210 |             [&app](const crow::Request& req, | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 3211 |                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 3212 |                    const std::string& systemName) { | 
| Carson Labrado | 3ba0007 | 2022-06-06 19:40:56 +0000 | [diff] [blame] | 3213 |         if (!redfish::setUpRedfishRoute(app, req, asyncResp)) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3214 |         { | 
 | 3215 |             return; | 
 | 3216 |         } | 
| Ed Tanous | 7f3e84a | 2022-12-28 16:22:54 -0800 | [diff] [blame] | 3217 |         if constexpr (bmcwebEnableMultiHost) | 
 | 3218 |         { | 
 | 3219 |             // Option currently returns no systems.  TBD | 
 | 3220 |             messages::resourceNotFound(asyncResp->res, "ComputerSystem", | 
 | 3221 |                                        systemName); | 
 | 3222 |             return; | 
 | 3223 |         } | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 3224 |         if (systemName != "system") | 
 | 3225 |         { | 
 | 3226 |             messages::resourceNotFound(asyncResp->res, "ComputerSystem", | 
 | 3227 |                                        systemName); | 
 | 3228 |             return; | 
 | 3229 |         } | 
 | 3230 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3231 |         // Copy over the static data to include the entries added by | 
 | 3232 |         // SubRoute | 
 | 3233 |         asyncResp->res.jsonValue["@odata.id"] = | 
 | 3234 |             "/redfish/v1/Systems/system/LogServices/Crashdump"; | 
 | 3235 |         asyncResp->res.jsonValue["@odata.type"] = | 
 | 3236 |             "#LogService.v1_2_0.LogService"; | 
 | 3237 |         asyncResp->res.jsonValue["Name"] = "Open BMC Oem Crashdump Service"; | 
 | 3238 |         asyncResp->res.jsonValue["Description"] = "Oem Crashdump Service"; | 
| V-Sanjana | 15b8972 | 2023-05-11 16:27:03 +0530 | [diff] [blame] | 3239 |         asyncResp->res.jsonValue["Id"] = "Crashdump"; | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3240 |         asyncResp->res.jsonValue["OverWritePolicy"] = "WrapsWhenFull"; | 
 | 3241 |         asyncResp->res.jsonValue["MaxNumberOfRecords"] = 3; | 
| Tejas Patil | 7c8c405 | 2021-06-04 17:43:14 +0530 | [diff] [blame] | 3242 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3243 |         std::pair<std::string, std::string> redfishDateTimeOffset = | 
| Ed Tanous | 2b82937 | 2022-08-03 14:22:34 -0700 | [diff] [blame] | 3244 |             redfish::time_utils::getDateTimeOffsetNow(); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3245 |         asyncResp->res.jsonValue["DateTime"] = redfishDateTimeOffset.first; | 
 | 3246 |         asyncResp->res.jsonValue["DateTimeLocalOffset"] = | 
 | 3247 |             redfishDateTimeOffset.second; | 
| Tejas Patil | 7c8c405 | 2021-06-04 17:43:14 +0530 | [diff] [blame] | 3248 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3249 |         asyncResp->res.jsonValue["Entries"]["@odata.id"] = | 
| Ed Tanous | ef4c65b | 2023-04-24 15:28:50 -0700 | [diff] [blame] | 3250 |             "/redfish/v1/Systems/system/LogServices/Crashdump/Entries"; | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3251 |         asyncResp->res.jsonValue["Actions"]["#LogService.ClearLog"]["target"] = | 
 | 3252 |             "/redfish/v1/Systems/system/LogServices/Crashdump/Actions/LogService.ClearLog"; | 
 | 3253 |         asyncResp->res.jsonValue["Actions"]["#LogService.CollectDiagnosticData"] | 
 | 3254 |                                 ["target"] = | 
 | 3255 |             "/redfish/v1/Systems/system/LogServices/Crashdump/Actions/LogService.CollectDiagnosticData"; | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 3256 |     }); | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 3257 | } | 
 | 3258 |  | 
 | 3259 | void inline requestRoutesCrashdumpClear(App& app) | 
 | 3260 | { | 
| George Liu | 0fda0f1 | 2021-11-16 10:06:17 +0800 | [diff] [blame] | 3261 |     BMCWEB_ROUTE( | 
 | 3262 |         app, | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 3263 |         "/redfish/v1/Systems/<str>/LogServices/Crashdump/Actions/LogService.ClearLog/") | 
| Ed Tanous | ed39821 | 2021-06-09 17:05:54 -0700 | [diff] [blame] | 3264 |         // This is incorrect, should be: | 
 | 3265 |         //.privileges(redfish::privileges::postLogService) | 
| Ed Tanous | 432a890 | 2021-06-14 15:28:56 -0700 | [diff] [blame] | 3266 |         .privileges({{"ConfigureComponents"}}) | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 3267 |         .methods(boost::beast::http::verb::post)( | 
| Ed Tanous | 45ca1b8 | 2022-03-25 13:07:27 -0700 | [diff] [blame] | 3268 |             [&app](const crow::Request& req, | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 3269 |                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 3270 |                    const std::string& systemName) { | 
| Carson Labrado | 3ba0007 | 2022-06-06 19:40:56 +0000 | [diff] [blame] | 3271 |         if (!redfish::setUpRedfishRoute(app, req, asyncResp)) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3272 |         { | 
 | 3273 |             return; | 
 | 3274 |         } | 
| Ed Tanous | 7f3e84a | 2022-12-28 16:22:54 -0800 | [diff] [blame] | 3275 |         if constexpr (bmcwebEnableMultiHost) | 
 | 3276 |         { | 
 | 3277 |             // Option currently returns no systems.  TBD | 
 | 3278 |             messages::resourceNotFound(asyncResp->res, "ComputerSystem", | 
 | 3279 |                                        systemName); | 
 | 3280 |             return; | 
 | 3281 |         } | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 3282 |         if (systemName != "system") | 
 | 3283 |         { | 
 | 3284 |             messages::resourceNotFound(asyncResp->res, "ComputerSystem", | 
 | 3285 |                                        systemName); | 
 | 3286 |             return; | 
 | 3287 |         } | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3288 |         crow::connections::systemBus->async_method_call( | 
| Ed Tanous | 5e7e2dc | 2023-02-16 10:37:01 -0800 | [diff] [blame] | 3289 |             [asyncResp](const boost::system::error_code& ec, | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3290 |                         const std::string&) { | 
 | 3291 |             if (ec) | 
 | 3292 |             { | 
 | 3293 |                 messages::internalError(asyncResp->res); | 
 | 3294 |                 return; | 
 | 3295 |             } | 
 | 3296 |             messages::success(asyncResp->res); | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 3297 |         }, | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3298 |             crashdumpObject, crashdumpPath, deleteAllInterface, "DeleteAll"); | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 3299 |     }); | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 3300 | } | 
| Jason M. Bills | 5b61b5e | 2019-10-16 10:59:02 -0700 | [diff] [blame] | 3301 |  | 
| zhanghch05 | 8d1b46d | 2021-04-01 11:18:24 +0800 | [diff] [blame] | 3302 | static void | 
 | 3303 |     logCrashdumpEntry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 3304 |                       const std::string& logID, nlohmann::json& logEntryJson) | 
| Jason M. Bills | e855dd2 | 2019-10-08 11:37:48 -0700 | [diff] [blame] | 3305 | { | 
| Johnathan Mantey | 043a053 | 2020-03-10 17:15:28 -0700 | [diff] [blame] | 3306 |     auto getStoredLogCallback = | 
| Ed Tanous | b9d36b4 | 2022-02-26 21:42:46 -0800 | [diff] [blame] | 3307 |         [asyncResp, logID, | 
| Ed Tanous | 5e7e2dc | 2023-02-16 10:37:01 -0800 | [diff] [blame] | 3308 |          &logEntryJson](const boost::system::error_code& ec, | 
| Ed Tanous | b9d36b4 | 2022-02-26 21:42:46 -0800 | [diff] [blame] | 3309 |                         const dbus::utility::DBusPropertiesMap& params) { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3310 |         if (ec) | 
 | 3311 |         { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 3312 |             BMCWEB_LOG_DEBUG("failed to get log ec: {}", ec.message()); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3313 |             if (ec.value() == | 
 | 3314 |                 boost::system::linux_error::bad_request_descriptor) | 
| Jason M. Bills | 1ddcf01 | 2019-11-26 14:59:21 -0800 | [diff] [blame] | 3315 |             { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3316 |                 messages::resourceNotFound(asyncResp->res, "LogEntry", logID); | 
| Jason M. Bills | 2b20ef6 | 2022-01-06 15:48:07 -0800 | [diff] [blame] | 3317 |             } | 
 | 3318 |             else | 
 | 3319 |             { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3320 |                 messages::internalError(asyncResp->res); | 
| Jason M. Bills | 2b20ef6 | 2022-01-06 15:48:07 -0800 | [diff] [blame] | 3321 |             } | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3322 |             return; | 
 | 3323 |         } | 
 | 3324 |  | 
 | 3325 |         std::string timestamp{}; | 
 | 3326 |         std::string filename{}; | 
 | 3327 |         std::string logfile{}; | 
 | 3328 |         parseCrashdumpParameters(params, filename, timestamp, logfile); | 
 | 3329 |  | 
 | 3330 |         if (filename.empty() || timestamp.empty()) | 
 | 3331 |         { | 
| Jiaqing Zhao | 9db4ba2 | 2022-10-09 17:24:40 +0800 | [diff] [blame] | 3332 |             messages::resourceNotFound(asyncResp->res, "LogEntry", logID); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3333 |             return; | 
 | 3334 |         } | 
 | 3335 |  | 
 | 3336 |         std::string crashdumpURI = | 
 | 3337 |             "/redfish/v1/Systems/system/LogServices/Crashdump/Entries/" + | 
 | 3338 |             logID + "/" + filename; | 
| Jason M. Bills | 84afc48 | 2022-06-24 12:38:23 -0700 | [diff] [blame] | 3339 |         nlohmann::json::object_t logEntry; | 
| Vijay Lobo | 9c11a17 | 2021-10-07 16:53:16 -0500 | [diff] [blame] | 3340 |         logEntry["@odata.type"] = "#LogEntry.v1_9_0.LogEntry"; | 
| Ed Tanous | ef4c65b | 2023-04-24 15:28:50 -0700 | [diff] [blame] | 3341 |         logEntry["@odata.id"] = boost::urls::format( | 
 | 3342 |             "/redfish/v1/Systems/system/LogServices/Crashdump/Entries/{}", | 
 | 3343 |             logID); | 
| Jason M. Bills | 84afc48 | 2022-06-24 12:38:23 -0700 | [diff] [blame] | 3344 |         logEntry["Name"] = "CPU Crashdump"; | 
 | 3345 |         logEntry["Id"] = logID; | 
 | 3346 |         logEntry["EntryType"] = "Oem"; | 
 | 3347 |         logEntry["AdditionalDataURI"] = std::move(crashdumpURI); | 
 | 3348 |         logEntry["DiagnosticDataType"] = "OEM"; | 
 | 3349 |         logEntry["OEMDiagnosticDataType"] = "PECICrashdump"; | 
 | 3350 |         logEntry["Created"] = std::move(timestamp); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3351 |  | 
 | 3352 |         // If logEntryJson references an array of LogEntry resources | 
 | 3353 |         // ('Members' list), then push this as a new entry, otherwise set it | 
 | 3354 |         // directly | 
 | 3355 |         if (logEntryJson.is_array()) | 
 | 3356 |         { | 
 | 3357 |             logEntryJson.push_back(logEntry); | 
 | 3358 |             asyncResp->res.jsonValue["Members@odata.count"] = | 
 | 3359 |                 logEntryJson.size(); | 
 | 3360 |         } | 
 | 3361 |         else | 
 | 3362 |         { | 
| Jason M. Bills | d405bb5 | 2022-06-24 10:52:05 -0700 | [diff] [blame] | 3363 |             logEntryJson.update(logEntry); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3364 |         } | 
 | 3365 |     }; | 
| Krzysztof Grobelny | d1bde9e | 2022-09-07 10:40:51 +0200 | [diff] [blame] | 3366 |     sdbusplus::asio::getAllProperties( | 
 | 3367 |         *crow::connections::systemBus, crashdumpObject, | 
 | 3368 |         crashdumpPath + std::string("/") + logID, crashdumpInterface, | 
 | 3369 |         std::move(getStoredLogCallback)); | 
| Jason M. Bills | e855dd2 | 2019-10-08 11:37:48 -0700 | [diff] [blame] | 3370 | } | 
 | 3371 |  | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 3372 | inline void requestRoutesCrashdumpEntryCollection(App& app) | 
| Ed Tanous | 1da66f7 | 2018-07-27 16:13:37 -0700 | [diff] [blame] | 3373 | { | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 3374 |     // Note: Deviated from redfish privilege registry for GET & HEAD | 
 | 3375 |     // method for security reasons. | 
| Ed Tanous | 1da66f7 | 2018-07-27 16:13:37 -0700 | [diff] [blame] | 3376 |     /** | 
 | 3377 |      * Functions triggers appropriate requests on DBus | 
 | 3378 |      */ | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 3379 |     BMCWEB_ROUTE(app, | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 3380 |                  "/redfish/v1/Systems/<str>/LogServices/Crashdump/Entries/") | 
| Ed Tanous | ed39821 | 2021-06-09 17:05:54 -0700 | [diff] [blame] | 3381 |         // This is incorrect, should be. | 
 | 3382 |         //.privileges(redfish::privileges::postLogEntryCollection) | 
| Ed Tanous | 432a890 | 2021-06-14 15:28:56 -0700 | [diff] [blame] | 3383 |         .privileges({{"ConfigureComponents"}}) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3384 |         .methods(boost::beast::http::verb::get)( | 
 | 3385 |             [&app](const crow::Request& req, | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 3386 |                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 3387 |                    const std::string& systemName) { | 
| Carson Labrado | 3ba0007 | 2022-06-06 19:40:56 +0000 | [diff] [blame] | 3388 |         if (!redfish::setUpRedfishRoute(app, req, asyncResp)) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3389 |         { | 
 | 3390 |             return; | 
 | 3391 |         } | 
| Ed Tanous | 7f3e84a | 2022-12-28 16:22:54 -0800 | [diff] [blame] | 3392 |         if constexpr (bmcwebEnableMultiHost) | 
 | 3393 |         { | 
 | 3394 |             // Option currently returns no systems.  TBD | 
 | 3395 |             messages::resourceNotFound(asyncResp->res, "ComputerSystem", | 
 | 3396 |                                        systemName); | 
 | 3397 |             return; | 
 | 3398 |         } | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 3399 |         if (systemName != "system") | 
 | 3400 |         { | 
 | 3401 |             messages::resourceNotFound(asyncResp->res, "ComputerSystem", | 
 | 3402 |                                        systemName); | 
 | 3403 |             return; | 
 | 3404 |         } | 
 | 3405 |  | 
| George Liu | 7a1dbc4 | 2022-12-07 16:03:22 +0800 | [diff] [blame] | 3406 |         constexpr std::array<std::string_view, 1> interfaces = { | 
 | 3407 |             crashdumpInterface}; | 
 | 3408 |         dbus::utility::getSubTreePaths( | 
 | 3409 |             "/", 0, interfaces, | 
 | 3410 |             [asyncResp](const boost::system::error_code& ec, | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3411 |                         const std::vector<std::string>& resp) { | 
 | 3412 |             if (ec) | 
| Ed Tanous | 45ca1b8 | 2022-03-25 13:07:27 -0700 | [diff] [blame] | 3413 |             { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3414 |                 if (ec.value() != | 
 | 3415 |                     boost::system::errc::no_such_file_or_directory) | 
 | 3416 |                 { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 3417 |                     BMCWEB_LOG_DEBUG("failed to get entries ec: {}", | 
 | 3418 |                                      ec.message()); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3419 |                     messages::internalError(asyncResp->res); | 
 | 3420 |                     return; | 
 | 3421 |                 } | 
| Ed Tanous | 45ca1b8 | 2022-03-25 13:07:27 -0700 | [diff] [blame] | 3422 |             } | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3423 |             asyncResp->res.jsonValue["@odata.type"] = | 
 | 3424 |                 "#LogEntryCollection.LogEntryCollection"; | 
 | 3425 |             asyncResp->res.jsonValue["@odata.id"] = | 
 | 3426 |                 "/redfish/v1/Systems/system/LogServices/Crashdump/Entries"; | 
 | 3427 |             asyncResp->res.jsonValue["Name"] = "Open BMC Crashdump Entries"; | 
 | 3428 |             asyncResp->res.jsonValue["Description"] = | 
 | 3429 |                 "Collection of Crashdump Entries"; | 
 | 3430 |             asyncResp->res.jsonValue["Members"] = nlohmann::json::array(); | 
 | 3431 |             asyncResp->res.jsonValue["Members@odata.count"] = 0; | 
| Jason M. Bills | 2b20ef6 | 2022-01-06 15:48:07 -0800 | [diff] [blame] | 3432 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3433 |             for (const std::string& path : resp) | 
 | 3434 |             { | 
 | 3435 |                 const sdbusplus::message::object_path objPath(path); | 
 | 3436 |                 // Get the log ID | 
 | 3437 |                 std::string logID = objPath.filename(); | 
 | 3438 |                 if (logID.empty()) | 
 | 3439 |                 { | 
 | 3440 |                     continue; | 
 | 3441 |                 } | 
 | 3442 |                 // Add the log entry to the array | 
 | 3443 |                 logCrashdumpEntry(asyncResp, logID, | 
 | 3444 |                                   asyncResp->res.jsonValue["Members"]); | 
 | 3445 |             } | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 3446 |         }); | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 3447 |     }); | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 3448 | } | 
| Ed Tanous | 1da66f7 | 2018-07-27 16:13:37 -0700 | [diff] [blame] | 3449 |  | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 3450 | inline void requestRoutesCrashdumpEntry(App& app) | 
| Ed Tanous | 1da66f7 | 2018-07-27 16:13:37 -0700 | [diff] [blame] | 3451 | { | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 3452 |     // Note: Deviated from redfish privilege registry for GET & HEAD | 
 | 3453 |     // method for security reasons. | 
| Ed Tanous | 1da66f7 | 2018-07-27 16:13:37 -0700 | [diff] [blame] | 3454 |  | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 3455 |     BMCWEB_ROUTE( | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 3456 |         app, "/redfish/v1/Systems/<str>/LogServices/Crashdump/Entries/<str>/") | 
| Ed Tanous | ed39821 | 2021-06-09 17:05:54 -0700 | [diff] [blame] | 3457 |         // this is incorrect, should be | 
 | 3458 |         // .privileges(redfish::privileges::getLogEntry) | 
| Ed Tanous | 432a890 | 2021-06-14 15:28:56 -0700 | [diff] [blame] | 3459 |         .privileges({{"ConfigureComponents"}}) | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 3460 |         .methods(boost::beast::http::verb::get)( | 
| Ed Tanous | 45ca1b8 | 2022-03-25 13:07:27 -0700 | [diff] [blame] | 3461 |             [&app](const crow::Request& req, | 
 | 3462 |                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 3463 |                    const std::string& systemName, const std::string& param) { | 
| Carson Labrado | 3ba0007 | 2022-06-06 19:40:56 +0000 | [diff] [blame] | 3464 |         if (!redfish::setUpRedfishRoute(app, req, asyncResp)) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3465 |         { | 
 | 3466 |             return; | 
 | 3467 |         } | 
| Ed Tanous | 7f3e84a | 2022-12-28 16:22:54 -0800 | [diff] [blame] | 3468 |         if constexpr (bmcwebEnableMultiHost) | 
 | 3469 |         { | 
 | 3470 |             // Option currently returns no systems.  TBD | 
 | 3471 |             messages::resourceNotFound(asyncResp->res, "ComputerSystem", | 
 | 3472 |                                        systemName); | 
 | 3473 |             return; | 
 | 3474 |         } | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 3475 |         if (systemName != "system") | 
 | 3476 |         { | 
 | 3477 |             messages::resourceNotFound(asyncResp->res, "ComputerSystem", | 
 | 3478 |                                        systemName); | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 3479 |             return; | 
 | 3480 |         } | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3481 |         const std::string& logID = param; | 
 | 3482 |         logCrashdumpEntry(asyncResp, logID, asyncResp->res.jsonValue); | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 3483 |     }); | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 3484 | } | 
| Ed Tanous | 1da66f7 | 2018-07-27 16:13:37 -0700 | [diff] [blame] | 3485 |  | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 3486 | inline void requestRoutesCrashdumpFile(App& app) | 
 | 3487 | { | 
 | 3488 |     // Note: Deviated from redfish privilege registry for GET & HEAD | 
 | 3489 |     // method for security reasons. | 
 | 3490 |     BMCWEB_ROUTE( | 
 | 3491 |         app, | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 3492 |         "/redfish/v1/Systems/<str>/LogServices/Crashdump/Entries/<str>/<str>/") | 
| Ed Tanous | ed39821 | 2021-06-09 17:05:54 -0700 | [diff] [blame] | 3493 |         .privileges(redfish::privileges::getLogEntry) | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 3494 |         .methods(boost::beast::http::verb::get)( | 
| Nan Zhou | a4ce114 | 2022-08-02 18:45:25 +0000 | [diff] [blame] | 3495 |             [](const crow::Request& req, | 
 | 3496 |                const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 3497 |                const std::string& systemName, const std::string& logID, | 
 | 3498 |                const std::string& fileName) { | 
| Shounak Mitra | 2a9beee | 2022-07-20 18:41:30 +0000 | [diff] [blame] | 3499 |         // Do not call getRedfishRoute here since the crashdump file is not a | 
 | 3500 |         // Redfish resource. | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 3501 |  | 
| Ed Tanous | 7f3e84a | 2022-12-28 16:22:54 -0800 | [diff] [blame] | 3502 |         if constexpr (bmcwebEnableMultiHost) | 
 | 3503 |         { | 
 | 3504 |             // Option currently returns no systems.  TBD | 
 | 3505 |             messages::resourceNotFound(asyncResp->res, "ComputerSystem", | 
 | 3506 |                                        systemName); | 
 | 3507 |             return; | 
 | 3508 |         } | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 3509 |         if (systemName != "system") | 
 | 3510 |         { | 
 | 3511 |             messages::resourceNotFound(asyncResp->res, "ComputerSystem", | 
 | 3512 |                                        systemName); | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 3513 |             return; | 
 | 3514 |         } | 
 | 3515 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3516 |         auto getStoredLogCallback = | 
| Ed Tanous | 39662a3 | 2023-02-06 15:09:46 -0800 | [diff] [blame] | 3517 |             [asyncResp, logID, fileName, url(boost::urls::url(req.url()))]( | 
| Ed Tanous | 5e7e2dc | 2023-02-16 10:37:01 -0800 | [diff] [blame] | 3518 |                 const boost::system::error_code& ec, | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3519 |                 const std::vector< | 
 | 3520 |                     std::pair<std::string, dbus::utility::DbusVariantType>>& | 
 | 3521 |                     resp) { | 
 | 3522 |             if (ec) | 
 | 3523 |             { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 3524 |                 BMCWEB_LOG_DEBUG("failed to get log ec: {}", ec.message()); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3525 |                 messages::internalError(asyncResp->res); | 
 | 3526 |                 return; | 
 | 3527 |             } | 
| Jason M. Bills | 8e6c099 | 2021-03-11 16:26:53 -0800 | [diff] [blame] | 3528 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3529 |             std::string dbusFilename{}; | 
 | 3530 |             std::string dbusTimestamp{}; | 
 | 3531 |             std::string dbusFilepath{}; | 
| Jason M. Bills | 8e6c099 | 2021-03-11 16:26:53 -0800 | [diff] [blame] | 3532 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3533 |             parseCrashdumpParameters(resp, dbusFilename, dbusTimestamp, | 
 | 3534 |                                      dbusFilepath); | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 3535 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3536 |             if (dbusFilename.empty() || dbusTimestamp.empty() || | 
 | 3537 |                 dbusFilepath.empty()) | 
 | 3538 |             { | 
| Jiaqing Zhao | 9db4ba2 | 2022-10-09 17:24:40 +0800 | [diff] [blame] | 3539 |                 messages::resourceNotFound(asyncResp->res, "LogEntry", logID); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3540 |                 return; | 
 | 3541 |             } | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 3542 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3543 |             // Verify the file name parameter is correct | 
 | 3544 |             if (fileName != dbusFilename) | 
 | 3545 |             { | 
| Jiaqing Zhao | 9db4ba2 | 2022-10-09 17:24:40 +0800 | [diff] [blame] | 3546 |                 messages::resourceNotFound(asyncResp->res, "LogEntry", logID); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3547 |                 return; | 
 | 3548 |             } | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 3549 |  | 
| Ed Tanous | 27b0cf9 | 2023-08-07 12:02:40 -0700 | [diff] [blame] | 3550 |             if (!asyncResp->res.openFile(dbusFilepath)) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3551 |             { | 
| Jiaqing Zhao | 9db4ba2 | 2022-10-09 17:24:40 +0800 | [diff] [blame] | 3552 |                 messages::resourceNotFound(asyncResp->res, "LogEntry", logID); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3553 |                 return; | 
 | 3554 |             } | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 3555 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3556 |             // Configure this to be a file download when accessed | 
 | 3557 |             // from a browser | 
| Ed Tanous | d9f6c62 | 2022-03-17 09:12:17 -0700 | [diff] [blame] | 3558 |             asyncResp->res.addHeader( | 
 | 3559 |                 boost::beast::http::field::content_disposition, "attachment"); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3560 |         }; | 
| Krzysztof Grobelny | d1bde9e | 2022-09-07 10:40:51 +0200 | [diff] [blame] | 3561 |         sdbusplus::asio::getAllProperties( | 
 | 3562 |             *crow::connections::systemBus, crashdumpObject, | 
 | 3563 |             crashdumpPath + std::string("/") + logID, crashdumpInterface, | 
 | 3564 |             std::move(getStoredLogCallback)); | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 3565 |     }); | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 3566 | } | 
 | 3567 |  | 
| Jason M. Bills | c5a4c82 | 2022-01-06 15:51:23 -0800 | [diff] [blame] | 3568 | enum class OEMDiagnosticType | 
 | 3569 | { | 
 | 3570 |     onDemand, | 
 | 3571 |     telemetry, | 
 | 3572 |     invalid, | 
 | 3573 | }; | 
 | 3574 |  | 
| Ed Tanous | 26ccae3 | 2023-02-16 10:28:44 -0800 | [diff] [blame] | 3575 | inline OEMDiagnosticType getOEMDiagnosticType(std::string_view oemDiagStr) | 
| Jason M. Bills | c5a4c82 | 2022-01-06 15:51:23 -0800 | [diff] [blame] | 3576 | { | 
 | 3577 |     if (oemDiagStr == "OnDemand") | 
 | 3578 |     { | 
 | 3579 |         return OEMDiagnosticType::onDemand; | 
 | 3580 |     } | 
 | 3581 |     if (oemDiagStr == "Telemetry") | 
 | 3582 |     { | 
 | 3583 |         return OEMDiagnosticType::telemetry; | 
 | 3584 |     } | 
 | 3585 |  | 
 | 3586 |     return OEMDiagnosticType::invalid; | 
 | 3587 | } | 
 | 3588 |  | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 3589 | inline void requestRoutesCrashdumpCollect(App& app) | 
 | 3590 | { | 
 | 3591 |     // Note: Deviated from redfish privilege registry for GET & HEAD | 
 | 3592 |     // method for security reasons. | 
| George Liu | 0fda0f1 | 2021-11-16 10:06:17 +0800 | [diff] [blame] | 3593 |     BMCWEB_ROUTE( | 
 | 3594 |         app, | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 3595 |         "/redfish/v1/Systems/<str>/LogServices/Crashdump/Actions/LogService.CollectDiagnosticData/") | 
| Ed Tanous | ed39821 | 2021-06-09 17:05:54 -0700 | [diff] [blame] | 3596 |         // The below is incorrect;  Should be ConfigureManager | 
 | 3597 |         //.privileges(redfish::privileges::postLogService) | 
| Ed Tanous | 432a890 | 2021-06-14 15:28:56 -0700 | [diff] [blame] | 3598 |         .privileges({{"ConfigureComponents"}}) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3599 |         .methods(boost::beast::http::verb::post)( | 
 | 3600 |             [&app](const crow::Request& req, | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 3601 |                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 3602 |                    const std::string& systemName) { | 
| Carson Labrado | 3ba0007 | 2022-06-06 19:40:56 +0000 | [diff] [blame] | 3603 |         if (!redfish::setUpRedfishRoute(app, req, asyncResp)) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3604 |         { | 
 | 3605 |             return; | 
 | 3606 |         } | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 3607 |  | 
| Ed Tanous | 7f3e84a | 2022-12-28 16:22:54 -0800 | [diff] [blame] | 3608 |         if constexpr (bmcwebEnableMultiHost) | 
 | 3609 |         { | 
 | 3610 |             // Option currently returns no systems.  TBD | 
 | 3611 |             messages::resourceNotFound(asyncResp->res, "ComputerSystem", | 
 | 3612 |                                        systemName); | 
 | 3613 |             return; | 
 | 3614 |         } | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 3615 |         if (systemName != "system") | 
 | 3616 |         { | 
 | 3617 |             messages::resourceNotFound(asyncResp->res, "ComputerSystem", | 
 | 3618 |                                        systemName); | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 3619 |             return; | 
 | 3620 |         } | 
 | 3621 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3622 |         std::string diagnosticDataType; | 
 | 3623 |         std::string oemDiagnosticDataType; | 
 | 3624 |         if (!redfish::json_util::readJsonAction( | 
 | 3625 |                 req, asyncResp->res, "DiagnosticDataType", diagnosticDataType, | 
 | 3626 |                 "OEMDiagnosticDataType", oemDiagnosticDataType)) | 
 | 3627 |         { | 
 | 3628 |             return; | 
 | 3629 |         } | 
 | 3630 |  | 
 | 3631 |         if (diagnosticDataType != "OEM") | 
 | 3632 |         { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 3633 |             BMCWEB_LOG_ERROR( | 
 | 3634 |                 "Only OEM DiagnosticDataType supported for Crashdump"); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3635 |             messages::actionParameterValueFormatError( | 
 | 3636 |                 asyncResp->res, diagnosticDataType, "DiagnosticDataType", | 
 | 3637 |                 "CollectDiagnosticData"); | 
 | 3638 |             return; | 
 | 3639 |         } | 
 | 3640 |  | 
 | 3641 |         OEMDiagnosticType oemDiagType = | 
 | 3642 |             getOEMDiagnosticType(oemDiagnosticDataType); | 
 | 3643 |  | 
 | 3644 |         std::string iface; | 
 | 3645 |         std::string method; | 
 | 3646 |         std::string taskMatchStr; | 
 | 3647 |         if (oemDiagType == OEMDiagnosticType::onDemand) | 
 | 3648 |         { | 
 | 3649 |             iface = crashdumpOnDemandInterface; | 
 | 3650 |             method = "GenerateOnDemandLog"; | 
 | 3651 |             taskMatchStr = "type='signal'," | 
 | 3652 |                            "interface='org.freedesktop.DBus.Properties'," | 
 | 3653 |                            "member='PropertiesChanged'," | 
 | 3654 |                            "arg0namespace='com.intel.crashdump'"; | 
 | 3655 |         } | 
 | 3656 |         else if (oemDiagType == OEMDiagnosticType::telemetry) | 
 | 3657 |         { | 
 | 3658 |             iface = crashdumpTelemetryInterface; | 
 | 3659 |             method = "GenerateTelemetryLog"; | 
 | 3660 |             taskMatchStr = "type='signal'," | 
 | 3661 |                            "interface='org.freedesktop.DBus.Properties'," | 
 | 3662 |                            "member='PropertiesChanged'," | 
 | 3663 |                            "arg0namespace='com.intel.crashdump'"; | 
 | 3664 |         } | 
 | 3665 |         else | 
 | 3666 |         { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 3667 |             BMCWEB_LOG_ERROR("Unsupported OEMDiagnosticDataType: {}", | 
 | 3668 |                              oemDiagnosticDataType); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3669 |             messages::actionParameterValueFormatError( | 
 | 3670 |                 asyncResp->res, oemDiagnosticDataType, "OEMDiagnosticDataType", | 
 | 3671 |                 "CollectDiagnosticData"); | 
 | 3672 |             return; | 
 | 3673 |         } | 
 | 3674 |  | 
 | 3675 |         auto collectCrashdumpCallback = | 
 | 3676 |             [asyncResp, payload(task::Payload(req)), | 
| Ed Tanous | 5e7e2dc | 2023-02-16 10:37:01 -0800 | [diff] [blame] | 3677 |              taskMatchStr](const boost::system::error_code& ec, | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3678 |                            const std::string&) mutable { | 
 | 3679 |             if (ec) | 
| Ed Tanous | 45ca1b8 | 2022-03-25 13:07:27 -0700 | [diff] [blame] | 3680 |             { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3681 |                 if (ec.value() == boost::system::errc::operation_not_supported) | 
 | 3682 |                 { | 
 | 3683 |                     messages::resourceInStandby(asyncResp->res); | 
 | 3684 |                 } | 
 | 3685 |                 else if (ec.value() == | 
 | 3686 |                          boost::system::errc::device_or_resource_busy) | 
 | 3687 |                 { | 
 | 3688 |                     messages::serviceTemporarilyUnavailable(asyncResp->res, | 
 | 3689 |                                                             "60"); | 
 | 3690 |                 } | 
 | 3691 |                 else | 
 | 3692 |                 { | 
 | 3693 |                     messages::internalError(asyncResp->res); | 
 | 3694 |                 } | 
| Ed Tanous | 45ca1b8 | 2022-03-25 13:07:27 -0700 | [diff] [blame] | 3695 |                 return; | 
 | 3696 |             } | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3697 |             std::shared_ptr<task::TaskData> task = task::TaskData::createTask( | 
| Ed Tanous | 8b24275 | 2023-06-27 17:17:13 -0700 | [diff] [blame] | 3698 |                 [](const boost::system::error_code& ec2, sdbusplus::message_t&, | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3699 |                    const std::shared_ptr<task::TaskData>& taskData) { | 
| Ed Tanous | 8b24275 | 2023-06-27 17:17:13 -0700 | [diff] [blame] | 3700 |                 if (!ec2) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3701 |                 { | 
 | 3702 |                     taskData->messages.emplace_back(messages::taskCompletedOK( | 
 | 3703 |                         std::to_string(taskData->index))); | 
 | 3704 |                     taskData->state = "Completed"; | 
 | 3705 |                 } | 
 | 3706 |                 return task::completed; | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 3707 |             }, | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3708 |                 taskMatchStr); | 
| Ed Tanous | 1da66f7 | 2018-07-27 16:13:37 -0700 | [diff] [blame] | 3709 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3710 |             task->startTimer(std::chrono::minutes(5)); | 
 | 3711 |             task->populateResp(asyncResp->res); | 
 | 3712 |             task->payload.emplace(std::move(payload)); | 
 | 3713 |         }; | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 3714 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3715 |         crow::connections::systemBus->async_method_call( | 
 | 3716 |             std::move(collectCrashdumpCallback), crashdumpObject, crashdumpPath, | 
 | 3717 |             iface, method); | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 3718 |     }); | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 3719 | } | 
| Kenny L. Ku | 6eda768 | 2020-06-19 09:48:36 -0700 | [diff] [blame] | 3720 |  | 
| Andrew Geissler | cb92c03 | 2018-08-17 07:56:14 -0700 | [diff] [blame] | 3721 | /** | 
 | 3722 |  * DBusLogServiceActionsClear class supports POST method for ClearLog action. | 
 | 3723 |  */ | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 3724 | inline void requestRoutesDBusLogServiceActionsClear(App& app) | 
| Andrew Geissler | cb92c03 | 2018-08-17 07:56:14 -0700 | [diff] [blame] | 3725 | { | 
| Andrew Geissler | cb92c03 | 2018-08-17 07:56:14 -0700 | [diff] [blame] | 3726 |     /** | 
 | 3727 |      * Function handles POST method request. | 
 | 3728 |      * The Clear Log actions does not require any parameter.The action deletes | 
 | 3729 |      * all entries found in the Entries collection for this Log Service. | 
 | 3730 |      */ | 
| Andrew Geissler | cb92c03 | 2018-08-17 07:56:14 -0700 | [diff] [blame] | 3731 |  | 
| George Liu | 0fda0f1 | 2021-11-16 10:06:17 +0800 | [diff] [blame] | 3732 |     BMCWEB_ROUTE( | 
 | 3733 |         app, | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 3734 |         "/redfish/v1/Systems/<str>/LogServices/EventLog/Actions/LogService.ClearLog/") | 
| Ed Tanous | ed39821 | 2021-06-09 17:05:54 -0700 | [diff] [blame] | 3735 |         .privileges(redfish::privileges::postLogService) | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 3736 |         .methods(boost::beast::http::verb::post)( | 
| Ed Tanous | 45ca1b8 | 2022-03-25 13:07:27 -0700 | [diff] [blame] | 3737 |             [&app](const crow::Request& req, | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 3738 |                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 3739 |                    const std::string& systemName) { | 
| Carson Labrado | 3ba0007 | 2022-06-06 19:40:56 +0000 | [diff] [blame] | 3740 |         if (!redfish::setUpRedfishRoute(app, req, asyncResp)) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3741 |         { | 
 | 3742 |             return; | 
 | 3743 |         } | 
| Ed Tanous | 7f3e84a | 2022-12-28 16:22:54 -0800 | [diff] [blame] | 3744 |         if constexpr (bmcwebEnableMultiHost) | 
 | 3745 |         { | 
 | 3746 |             // Option currently returns no systems.  TBD | 
 | 3747 |             messages::resourceNotFound(asyncResp->res, "ComputerSystem", | 
 | 3748 |                                        systemName); | 
 | 3749 |             return; | 
 | 3750 |         } | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 3751 |         if (systemName != "system") | 
 | 3752 |         { | 
 | 3753 |             messages::resourceNotFound(asyncResp->res, "ComputerSystem", | 
 | 3754 |                                        systemName); | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 3755 |             return; | 
 | 3756 |         } | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 3757 |         BMCWEB_LOG_DEBUG("Do delete all entries."); | 
| Andrew Geissler | cb92c03 | 2018-08-17 07:56:14 -0700 | [diff] [blame] | 3758 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3759 |         // Process response from Logging service. | 
| Ed Tanous | 5e7e2dc | 2023-02-16 10:37:01 -0800 | [diff] [blame] | 3760 |         auto respHandler = [asyncResp](const boost::system::error_code& ec) { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 3761 |             BMCWEB_LOG_DEBUG("doClearLog resp_handler callback: Done"); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3762 |             if (ec) | 
 | 3763 |             { | 
 | 3764 |                 // TODO Handle for specific error code | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 3765 |                 BMCWEB_LOG_ERROR("doClearLog resp_handler got error {}", ec); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3766 |                 asyncResp->res.result( | 
 | 3767 |                     boost::beast::http::status::internal_server_error); | 
 | 3768 |                 return; | 
 | 3769 |             } | 
| Andrew Geissler | cb92c03 | 2018-08-17 07:56:14 -0700 | [diff] [blame] | 3770 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3771 |             asyncResp->res.result(boost::beast::http::status::no_content); | 
 | 3772 |         }; | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 3773 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3774 |         // Make call to Logging service to request Clear Log | 
 | 3775 |         crow::connections::systemBus->async_method_call( | 
 | 3776 |             respHandler, "xyz.openbmc_project.Logging", | 
 | 3777 |             "/xyz/openbmc_project/logging", | 
 | 3778 |             "xyz.openbmc_project.Collection.DeleteAll", "DeleteAll"); | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 3779 |     }); | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 3780 | } | 
| ZhikuiRen | a3316fc | 2020-01-29 14:58:08 -0800 | [diff] [blame] | 3781 |  | 
 | 3782 | /**************************************************** | 
 | 3783 |  * Redfish PostCode interfaces | 
 | 3784 |  * using DBUS interface: getPostCodesTS | 
 | 3785 |  ******************************************************/ | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 3786 | inline void requestRoutesPostCodesLogService(App& app) | 
| ZhikuiRen | a3316fc | 2020-01-29 14:58:08 -0800 | [diff] [blame] | 3787 | { | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 3788 |     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/PostCodes/") | 
| Ed Tanous | ed39821 | 2021-06-09 17:05:54 -0700 | [diff] [blame] | 3789 |         .privileges(redfish::privileges::getLogService) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3790 |         .methods(boost::beast::http::verb::get)( | 
 | 3791 |             [&app](const crow::Request& req, | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 3792 |                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 3793 |                    const std::string& systemName) { | 
| Carson Labrado | 3ba0007 | 2022-06-06 19:40:56 +0000 | [diff] [blame] | 3794 |         if (!redfish::setUpRedfishRoute(app, req, asyncResp)) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3795 |         { | 
 | 3796 |             return; | 
 | 3797 |         } | 
| Ed Tanous | 7f3e84a | 2022-12-28 16:22:54 -0800 | [diff] [blame] | 3798 |         if constexpr (bmcwebEnableMultiHost) | 
 | 3799 |         { | 
 | 3800 |             // Option currently returns no systems.  TBD | 
 | 3801 |             messages::resourceNotFound(asyncResp->res, "ComputerSystem", | 
 | 3802 |                                        systemName); | 
 | 3803 |             return; | 
 | 3804 |         } | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 3805 |         if (systemName != "system") | 
 | 3806 |         { | 
 | 3807 |             messages::resourceNotFound(asyncResp->res, "ComputerSystem", | 
 | 3808 |                                        systemName); | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 3809 |             return; | 
 | 3810 |         } | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3811 |         asyncResp->res.jsonValue["@odata.id"] = | 
 | 3812 |             "/redfish/v1/Systems/system/LogServices/PostCodes"; | 
 | 3813 |         asyncResp->res.jsonValue["@odata.type"] = | 
| Janet Adkins | b25644a | 2023-08-16 11:23:45 -0500 | [diff] [blame] | 3814 |             "#LogService.v1_2_0.LogService"; | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3815 |         asyncResp->res.jsonValue["Name"] = "POST Code Log Service"; | 
 | 3816 |         asyncResp->res.jsonValue["Description"] = "POST Code Log Service"; | 
| Ed Tanous | ed34a4a | 2023-02-08 15:43:27 -0800 | [diff] [blame] | 3817 |         asyncResp->res.jsonValue["Id"] = "PostCodes"; | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3818 |         asyncResp->res.jsonValue["OverWritePolicy"] = "WrapsWhenFull"; | 
 | 3819 |         asyncResp->res.jsonValue["Entries"]["@odata.id"] = | 
 | 3820 |             "/redfish/v1/Systems/system/LogServices/PostCodes/Entries"; | 
| Tejas Patil | 7c8c405 | 2021-06-04 17:43:14 +0530 | [diff] [blame] | 3821 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3822 |         std::pair<std::string, std::string> redfishDateTimeOffset = | 
| Ed Tanous | 2b82937 | 2022-08-03 14:22:34 -0700 | [diff] [blame] | 3823 |             redfish::time_utils::getDateTimeOffsetNow(); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3824 |         asyncResp->res.jsonValue["DateTime"] = redfishDateTimeOffset.first; | 
 | 3825 |         asyncResp->res.jsonValue["DateTimeLocalOffset"] = | 
 | 3826 |             redfishDateTimeOffset.second; | 
| Tejas Patil | 7c8c405 | 2021-06-04 17:43:14 +0530 | [diff] [blame] | 3827 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3828 |         asyncResp->res.jsonValue["Actions"]["#LogService.ClearLog"] = { | 
 | 3829 |             {"target", | 
 | 3830 |              "/redfish/v1/Systems/system/LogServices/PostCodes/Actions/LogService.ClearLog"}}; | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 3831 |     }); | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 3832 | } | 
| ZhikuiRen | a3316fc | 2020-01-29 14:58:08 -0800 | [diff] [blame] | 3833 |  | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 3834 | inline void requestRoutesPostCodesClear(App& app) | 
| ZhikuiRen | a3316fc | 2020-01-29 14:58:08 -0800 | [diff] [blame] | 3835 | { | 
| George Liu | 0fda0f1 | 2021-11-16 10:06:17 +0800 | [diff] [blame] | 3836 |     BMCWEB_ROUTE( | 
 | 3837 |         app, | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 3838 |         "/redfish/v1/Systems/<str>/LogServices/PostCodes/Actions/LogService.ClearLog/") | 
| Ed Tanous | ed39821 | 2021-06-09 17:05:54 -0700 | [diff] [blame] | 3839 |         // The following privilege is incorrect;  It should be ConfigureManager | 
 | 3840 |         //.privileges(redfish::privileges::postLogService) | 
| Ed Tanous | 432a890 | 2021-06-14 15:28:56 -0700 | [diff] [blame] | 3841 |         .privileges({{"ConfigureComponents"}}) | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 3842 |         .methods(boost::beast::http::verb::post)( | 
| Ed Tanous | 45ca1b8 | 2022-03-25 13:07:27 -0700 | [diff] [blame] | 3843 |             [&app](const crow::Request& req, | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 3844 |                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 3845 |                    const std::string& systemName) { | 
| Carson Labrado | 3ba0007 | 2022-06-06 19:40:56 +0000 | [diff] [blame] | 3846 |         if (!redfish::setUpRedfishRoute(app, req, asyncResp)) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3847 |         { | 
 | 3848 |             return; | 
 | 3849 |         } | 
| Ed Tanous | 7f3e84a | 2022-12-28 16:22:54 -0800 | [diff] [blame] | 3850 |         if constexpr (bmcwebEnableMultiHost) | 
 | 3851 |         { | 
 | 3852 |             // Option currently returns no systems.  TBD | 
 | 3853 |             messages::resourceNotFound(asyncResp->res, "ComputerSystem", | 
 | 3854 |                                        systemName); | 
 | 3855 |             return; | 
 | 3856 |         } | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 3857 |         if (systemName != "system") | 
 | 3858 |         { | 
 | 3859 |             messages::resourceNotFound(asyncResp->res, "ComputerSystem", | 
 | 3860 |                                        systemName); | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 3861 |             return; | 
 | 3862 |         } | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 3863 |         BMCWEB_LOG_DEBUG("Do delete all postcodes entries."); | 
| ZhikuiRen | a3316fc | 2020-01-29 14:58:08 -0800 | [diff] [blame] | 3864 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3865 |         // Make call to post-code service to request clear all | 
 | 3866 |         crow::connections::systemBus->async_method_call( | 
| Ed Tanous | 5e7e2dc | 2023-02-16 10:37:01 -0800 | [diff] [blame] | 3867 |             [asyncResp](const boost::system::error_code& ec) { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3868 |             if (ec) | 
 | 3869 |             { | 
 | 3870 |                 // TODO Handle for specific error code | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 3871 |                 BMCWEB_LOG_ERROR("doClearPostCodes resp_handler got error {}", | 
 | 3872 |                                  ec); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3873 |                 asyncResp->res.result( | 
 | 3874 |                     boost::beast::http::status::internal_server_error); | 
 | 3875 |                 messages::internalError(asyncResp->res); | 
 | 3876 |                 return; | 
 | 3877 |             } | 
| Tony Lee | 18fc70c | 2023-08-24 16:15:54 +0800 | [diff] [blame] | 3878 |             messages::success(asyncResp->res); | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 3879 |         }, | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 3880 |             "xyz.openbmc_project.State.Boot.PostCode0", | 
 | 3881 |             "/xyz/openbmc_project/State/Boot/PostCode0", | 
 | 3882 |             "xyz.openbmc_project.Collection.DeleteAll", "DeleteAll"); | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 3883 |     }); | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 3884 | } | 
| ZhikuiRen | a3316fc | 2020-01-29 14:58:08 -0800 | [diff] [blame] | 3885 |  | 
| Jiaqing Zhao | 6f284d2 | 2022-10-10 15:56:45 +0800 | [diff] [blame] | 3886 | /** | 
 | 3887 |  * @brief Parse post code ID and get the current value and index value | 
 | 3888 |  *        eg: postCodeID=B1-2, currentValue=1, index=2 | 
 | 3889 |  * | 
 | 3890 |  * @param[in]  postCodeID     Post Code ID | 
 | 3891 |  * @param[out] currentValue   Current value | 
 | 3892 |  * @param[out] index          Index value | 
 | 3893 |  * | 
 | 3894 |  * @return bool true if the parsing is successful, false the parsing fails | 
 | 3895 |  */ | 
 | 3896 | inline static bool parsePostCode(const std::string& postCodeID, | 
 | 3897 |                                  uint64_t& currentValue, uint16_t& index) | 
 | 3898 | { | 
 | 3899 |     std::vector<std::string> split; | 
| Ed Tanous | 50ebd4a | 2023-01-19 19:03:17 -0800 | [diff] [blame] | 3900 |     bmcweb::split(split, postCodeID, '-'); | 
| Jiaqing Zhao | 6f284d2 | 2022-10-10 15:56:45 +0800 | [diff] [blame] | 3901 |     if (split.size() != 2 || split[0].length() < 2 || split[0].front() != 'B') | 
 | 3902 |     { | 
 | 3903 |         return false; | 
 | 3904 |     } | 
 | 3905 |  | 
| Patrick Williams | 84396af | 2023-05-11 11:47:45 -0500 | [diff] [blame] | 3906 |     auto start = std::next(split[0].begin()); | 
 | 3907 |     auto end = split[0].end(); | 
 | 3908 |     auto [ptrIndex, ecIndex] = std::from_chars(&*start, &*end, index); | 
| Jiaqing Zhao | 6f284d2 | 2022-10-10 15:56:45 +0800 | [diff] [blame] | 3909 |  | 
| Patrick Williams | 84396af | 2023-05-11 11:47:45 -0500 | [diff] [blame] | 3910 |     if (ptrIndex != &*end || ecIndex != std::errc()) | 
| Jiaqing Zhao | 6f284d2 | 2022-10-10 15:56:45 +0800 | [diff] [blame] | 3911 |     { | 
 | 3912 |         return false; | 
 | 3913 |     } | 
 | 3914 |  | 
| Patrick Williams | 84396af | 2023-05-11 11:47:45 -0500 | [diff] [blame] | 3915 |     start = split[1].begin(); | 
 | 3916 |     end = split[1].end(); | 
| Jiaqing Zhao | 6f284d2 | 2022-10-10 15:56:45 +0800 | [diff] [blame] | 3917 |  | 
| Patrick Williams | 84396af | 2023-05-11 11:47:45 -0500 | [diff] [blame] | 3918 |     auto [ptrValue, ecValue] = std::from_chars(&*start, &*end, currentValue); | 
| Jiaqing Zhao | 6f284d2 | 2022-10-10 15:56:45 +0800 | [diff] [blame] | 3919 |  | 
| Patrick Williams | 84396af | 2023-05-11 11:47:45 -0500 | [diff] [blame] | 3920 |     return ptrValue == &*end && ecValue == std::errc(); | 
| Jiaqing Zhao | 6f284d2 | 2022-10-10 15:56:45 +0800 | [diff] [blame] | 3921 | } | 
 | 3922 |  | 
 | 3923 | static bool fillPostCodeEntry( | 
| Ed Tanous | ac106bf | 2023-06-07 09:24:59 -0700 | [diff] [blame] | 3924 |     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
| Manojkiran Eda | 6c9a279 | 2021-02-27 14:25:04 +0530 | [diff] [blame] | 3925 |     const boost::container::flat_map< | 
 | 3926 |         uint64_t, std::tuple<uint64_t, std::vector<uint8_t>>>& postcode, | 
| ZhikuiRen | a3316fc | 2020-01-29 14:58:08 -0800 | [diff] [blame] | 3927 |     const uint16_t bootIndex, const uint64_t codeIndex = 0, | 
 | 3928 |     const uint64_t skip = 0, const uint64_t top = 0) | 
 | 3929 | { | 
 | 3930 |     // Get the Message from the MessageRegistry | 
| Ed Tanous | fffb8c1 | 2022-02-07 23:53:03 -0800 | [diff] [blame] | 3931 |     const registries::Message* message = | 
 | 3932 |         registries::getMessage("OpenBMC.0.2.BIOSPOSTCode"); | 
| ZhikuiRen | a3316fc | 2020-01-29 14:58:08 -0800 | [diff] [blame] | 3933 |  | 
 | 3934 |     uint64_t currentCodeIndex = 0; | 
| ZhikuiRen | a3316fc | 2020-01-29 14:58:08 -0800 | [diff] [blame] | 3935 |     uint64_t firstCodeTimeUs = 0; | 
| Manojkiran Eda | 6c9a279 | 2021-02-27 14:25:04 +0530 | [diff] [blame] | 3936 |     for (const std::pair<uint64_t, std::tuple<uint64_t, std::vector<uint8_t>>>& | 
 | 3937 |              code : postcode) | 
| ZhikuiRen | a3316fc | 2020-01-29 14:58:08 -0800 | [diff] [blame] | 3938 |     { | 
 | 3939 |         currentCodeIndex++; | 
 | 3940 |         std::string postcodeEntryID = | 
 | 3941 |             "B" + std::to_string(bootIndex) + "-" + | 
 | 3942 |             std::to_string(currentCodeIndex); // 1 based index in EntryID string | 
 | 3943 |  | 
 | 3944 |         uint64_t usecSinceEpoch = code.first; | 
 | 3945 |         uint64_t usTimeOffset = 0; | 
 | 3946 |  | 
 | 3947 |         if (1 == currentCodeIndex) | 
 | 3948 |         { // already incremented | 
 | 3949 |             firstCodeTimeUs = code.first; | 
 | 3950 |         } | 
 | 3951 |         else | 
 | 3952 |         { | 
 | 3953 |             usTimeOffset = code.first - firstCodeTimeUs; | 
 | 3954 |         } | 
 | 3955 |  | 
 | 3956 |         // skip if no specific codeIndex is specified and currentCodeIndex does | 
 | 3957 |         // not fall between top and skip | 
 | 3958 |         if ((codeIndex == 0) && | 
 | 3959 |             (currentCodeIndex <= skip || currentCodeIndex > top)) | 
 | 3960 |         { | 
 | 3961 |             continue; | 
 | 3962 |         } | 
 | 3963 |  | 
| Gunnar Mills | 4e0453b | 2020-07-08 14:00:30 -0500 | [diff] [blame] | 3964 |         // skip if a specific codeIndex is specified and does not match the | 
| ZhikuiRen | a3316fc | 2020-01-29 14:58:08 -0800 | [diff] [blame] | 3965 |         // currentIndex | 
 | 3966 |         if ((codeIndex > 0) && (currentCodeIndex != codeIndex)) | 
 | 3967 |         { | 
 | 3968 |             // This is done for simplicity. 1st entry is needed to calculate | 
 | 3969 |             // time offset. To improve efficiency, one can get to the entry | 
 | 3970 |             // directly (possibly with flatmap's nth method) | 
 | 3971 |             continue; | 
 | 3972 |         } | 
 | 3973 |  | 
 | 3974 |         // currentCodeIndex is within top and skip or equal to specified code | 
 | 3975 |         // index | 
 | 3976 |  | 
 | 3977 |         // Get the Created time from the timestamp | 
 | 3978 |         std::string entryTimeStr; | 
| Konstantin Aladyshev | 2a02561 | 2023-02-15 11:52:58 +0300 | [diff] [blame] | 3979 |         entryTimeStr = redfish::time_utils::getDateTimeUintUs(usecSinceEpoch); | 
| ZhikuiRen | a3316fc | 2020-01-29 14:58:08 -0800 | [diff] [blame] | 3980 |  | 
 | 3981 |         // assemble messageArgs: BootIndex, TimeOffset(100us), PostCode(hex) | 
 | 3982 |         std::ostringstream hexCode; | 
 | 3983 |         hexCode << "0x" << std::setfill('0') << std::setw(2) << std::hex | 
| Manojkiran Eda | 6c9a279 | 2021-02-27 14:25:04 +0530 | [diff] [blame] | 3984 |                 << std::get<0>(code.second); | 
| ZhikuiRen | a3316fc | 2020-01-29 14:58:08 -0800 | [diff] [blame] | 3985 |         std::ostringstream timeOffsetStr; | 
 | 3986 |         // Set Fixed -Point Notation | 
 | 3987 |         timeOffsetStr << std::fixed; | 
 | 3988 |         // Set precision to 4 digits | 
 | 3989 |         timeOffsetStr << std::setprecision(4); | 
 | 3990 |         // Add double to stream | 
 | 3991 |         timeOffsetStr << static_cast<double>(usTimeOffset) / 1000 / 1000; | 
| ZhikuiRen | a3316fc | 2020-01-29 14:58:08 -0800 | [diff] [blame] | 3992 |  | 
| Ed Tanous | 1e6deaf | 2022-02-17 11:32:37 -0800 | [diff] [blame] | 3993 |         std::string bootIndexStr = std::to_string(bootIndex); | 
 | 3994 |         std::string timeOffsetString = timeOffsetStr.str(); | 
 | 3995 |         std::string hexCodeStr = hexCode.str(); | 
 | 3996 |  | 
 | 3997 |         std::array<std::string_view, 3> messageArgs = { | 
 | 3998 |             bootIndexStr, timeOffsetString, hexCodeStr}; | 
 | 3999 |  | 
 | 4000 |         std::string msg = | 
 | 4001 |             redfish::registries::fillMessageArgs(messageArgs, message->message); | 
 | 4002 |         if (msg.empty()) | 
| ZhikuiRen | a3316fc | 2020-01-29 14:58:08 -0800 | [diff] [blame] | 4003 |         { | 
| Ed Tanous | 1e6deaf | 2022-02-17 11:32:37 -0800 | [diff] [blame] | 4004 |             messages::internalError(asyncResp->res); | 
 | 4005 |             return false; | 
| ZhikuiRen | a3316fc | 2020-01-29 14:58:08 -0800 | [diff] [blame] | 4006 |         } | 
 | 4007 |  | 
| Tim Lee | d4342a9 | 2020-04-27 11:47:58 +0800 | [diff] [blame] | 4008 |         // Get Severity template from message registry | 
 | 4009 |         std::string severity; | 
 | 4010 |         if (message != nullptr) | 
 | 4011 |         { | 
| Ed Tanous | 5f2b84e | 2022-02-08 00:41:53 -0800 | [diff] [blame] | 4012 |             severity = message->messageSeverity; | 
| Tim Lee | d4342a9 | 2020-04-27 11:47:58 +0800 | [diff] [blame] | 4013 |         } | 
 | 4014 |  | 
| Jiaqing Zhao | 6f284d2 | 2022-10-10 15:56:45 +0800 | [diff] [blame] | 4015 |         // Format entry | 
 | 4016 |         nlohmann::json::object_t bmcLogEntry; | 
| Vijay Lobo | 9c11a17 | 2021-10-07 16:53:16 -0500 | [diff] [blame] | 4017 |         bmcLogEntry["@odata.type"] = "#LogEntry.v1_9_0.LogEntry"; | 
| Ed Tanous | ef4c65b | 2023-04-24 15:28:50 -0700 | [diff] [blame] | 4018 |         bmcLogEntry["@odata.id"] = boost::urls::format( | 
 | 4019 |             "/redfish/v1/Systems/system/LogServices/PostCodes/Entries/{}", | 
 | 4020 |             postcodeEntryID); | 
| Jason M. Bills | 84afc48 | 2022-06-24 12:38:23 -0700 | [diff] [blame] | 4021 |         bmcLogEntry["Name"] = "POST Code Log Entry"; | 
 | 4022 |         bmcLogEntry["Id"] = postcodeEntryID; | 
 | 4023 |         bmcLogEntry["Message"] = std::move(msg); | 
 | 4024 |         bmcLogEntry["MessageId"] = "OpenBMC.0.2.BIOSPOSTCode"; | 
| Ed Tanous | 1e6deaf | 2022-02-17 11:32:37 -0800 | [diff] [blame] | 4025 |         bmcLogEntry["MessageArgs"] = messageArgs; | 
| Jason M. Bills | 84afc48 | 2022-06-24 12:38:23 -0700 | [diff] [blame] | 4026 |         bmcLogEntry["EntryType"] = "Event"; | 
 | 4027 |         bmcLogEntry["Severity"] = std::move(severity); | 
 | 4028 |         bmcLogEntry["Created"] = entryTimeStr; | 
| George Liu | 647b3cd | 2021-07-05 12:43:56 +0800 | [diff] [blame] | 4029 |         if (!std::get<std::vector<uint8_t>>(code.second).empty()) | 
 | 4030 |         { | 
 | 4031 |             bmcLogEntry["AdditionalDataURI"] = | 
 | 4032 |                 "/redfish/v1/Systems/system/LogServices/PostCodes/Entries/" + | 
 | 4033 |                 postcodeEntryID + "/attachment"; | 
 | 4034 |         } | 
| Jiaqing Zhao | 6f284d2 | 2022-10-10 15:56:45 +0800 | [diff] [blame] | 4035 |  | 
 | 4036 |         // codeIndex is only specified when querying single entry, return only | 
 | 4037 |         // that entry in this case | 
 | 4038 |         if (codeIndex != 0) | 
 | 4039 |         { | 
| Ed Tanous | ac106bf | 2023-06-07 09:24:59 -0700 | [diff] [blame] | 4040 |             asyncResp->res.jsonValue.update(bmcLogEntry); | 
| Jiaqing Zhao | 6f284d2 | 2022-10-10 15:56:45 +0800 | [diff] [blame] | 4041 |             return true; | 
 | 4042 |         } | 
 | 4043 |  | 
| Ed Tanous | ac106bf | 2023-06-07 09:24:59 -0700 | [diff] [blame] | 4044 |         nlohmann::json& logEntryArray = asyncResp->res.jsonValue["Members"]; | 
| Patrick Williams | b2ba307 | 2023-05-12 10:27:39 -0500 | [diff] [blame] | 4045 |         logEntryArray.emplace_back(std::move(bmcLogEntry)); | 
| ZhikuiRen | a3316fc | 2020-01-29 14:58:08 -0800 | [diff] [blame] | 4046 |     } | 
| Jiaqing Zhao | 6f284d2 | 2022-10-10 15:56:45 +0800 | [diff] [blame] | 4047 |  | 
 | 4048 |     // Return value is always false when querying multiple entries | 
 | 4049 |     return false; | 
| ZhikuiRen | a3316fc | 2020-01-29 14:58:08 -0800 | [diff] [blame] | 4050 | } | 
 | 4051 |  | 
| Ed Tanous | ac106bf | 2023-06-07 09:24:59 -0700 | [diff] [blame] | 4052 | static void | 
 | 4053 |     getPostCodeForEntry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 4054 |                         const std::string& entryId) | 
| ZhikuiRen | a3316fc | 2020-01-29 14:58:08 -0800 | [diff] [blame] | 4055 | { | 
| Jiaqing Zhao | 6f284d2 | 2022-10-10 15:56:45 +0800 | [diff] [blame] | 4056 |     uint16_t bootIndex = 0; | 
 | 4057 |     uint64_t codeIndex = 0; | 
 | 4058 |     if (!parsePostCode(entryId, codeIndex, bootIndex)) | 
 | 4059 |     { | 
 | 4060 |         // Requested ID was not found | 
| Ed Tanous | ac106bf | 2023-06-07 09:24:59 -0700 | [diff] [blame] | 4061 |         messages::resourceNotFound(asyncResp->res, "LogEntry", entryId); | 
| Jiaqing Zhao | 6f284d2 | 2022-10-10 15:56:45 +0800 | [diff] [blame] | 4062 |         return; | 
 | 4063 |     } | 
 | 4064 |  | 
 | 4065 |     if (bootIndex == 0 || codeIndex == 0) | 
 | 4066 |     { | 
 | 4067 |         // 0 is an invalid index | 
| Ed Tanous | ac106bf | 2023-06-07 09:24:59 -0700 | [diff] [blame] | 4068 |         messages::resourceNotFound(asyncResp->res, "LogEntry", entryId); | 
| Jiaqing Zhao | 6f284d2 | 2022-10-10 15:56:45 +0800 | [diff] [blame] | 4069 |         return; | 
 | 4070 |     } | 
 | 4071 |  | 
| ZhikuiRen | a3316fc | 2020-01-29 14:58:08 -0800 | [diff] [blame] | 4072 |     crow::connections::systemBus->async_method_call( | 
| Ed Tanous | ac106bf | 2023-06-07 09:24:59 -0700 | [diff] [blame] | 4073 |         [asyncResp, entryId, bootIndex, | 
| Ed Tanous | 5e7e2dc | 2023-02-16 10:37:01 -0800 | [diff] [blame] | 4074 |          codeIndex](const boost::system::error_code& ec, | 
| Manojkiran Eda | 6c9a279 | 2021-02-27 14:25:04 +0530 | [diff] [blame] | 4075 |                     const boost::container::flat_map< | 
 | 4076 |                         uint64_t, std::tuple<uint64_t, std::vector<uint8_t>>>& | 
 | 4077 |                         postcode) { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 4078 |         if (ec) | 
 | 4079 |         { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 4080 |             BMCWEB_LOG_DEBUG("DBUS POST CODE PostCode response error"); | 
| Ed Tanous | ac106bf | 2023-06-07 09:24:59 -0700 | [diff] [blame] | 4081 |             messages::internalError(asyncResp->res); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 4082 |             return; | 
 | 4083 |         } | 
| ZhikuiRen | a3316fc | 2020-01-29 14:58:08 -0800 | [diff] [blame] | 4084 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 4085 |         if (postcode.empty()) | 
 | 4086 |         { | 
| Ed Tanous | ac106bf | 2023-06-07 09:24:59 -0700 | [diff] [blame] | 4087 |             messages::resourceNotFound(asyncResp->res, "LogEntry", entryId); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 4088 |             return; | 
 | 4089 |         } | 
| ZhikuiRen | a3316fc | 2020-01-29 14:58:08 -0800 | [diff] [blame] | 4090 |  | 
| Ed Tanous | ac106bf | 2023-06-07 09:24:59 -0700 | [diff] [blame] | 4091 |         if (!fillPostCodeEntry(asyncResp, postcode, bootIndex, codeIndex)) | 
| Jiaqing Zhao | 6f284d2 | 2022-10-10 15:56:45 +0800 | [diff] [blame] | 4092 |         { | 
| Ed Tanous | ac106bf | 2023-06-07 09:24:59 -0700 | [diff] [blame] | 4093 |             messages::resourceNotFound(asyncResp->res, "LogEntry", entryId); | 
| Jiaqing Zhao | 6f284d2 | 2022-10-10 15:56:45 +0800 | [diff] [blame] | 4094 |             return; | 
 | 4095 |         } | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 4096 |     }, | 
| Jonathan Doman | 1512476 | 2021-01-07 17:54:17 -0800 | [diff] [blame] | 4097 |         "xyz.openbmc_project.State.Boot.PostCode0", | 
 | 4098 |         "/xyz/openbmc_project/State/Boot/PostCode0", | 
| ZhikuiRen | a3316fc | 2020-01-29 14:58:08 -0800 | [diff] [blame] | 4099 |         "xyz.openbmc_project.State.Boot.PostCode", "GetPostCodesWithTimeStamp", | 
 | 4100 |         bootIndex); | 
 | 4101 | } | 
 | 4102 |  | 
| Ed Tanous | ac106bf | 2023-06-07 09:24:59 -0700 | [diff] [blame] | 4103 | static void | 
 | 4104 |     getPostCodeForBoot(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 4105 |                        const uint16_t bootIndex, const uint16_t bootCount, | 
 | 4106 |                        const uint64_t entryCount, size_t skip, size_t top) | 
| ZhikuiRen | a3316fc | 2020-01-29 14:58:08 -0800 | [diff] [blame] | 4107 | { | 
 | 4108 |     crow::connections::systemBus->async_method_call( | 
| Ed Tanous | ac106bf | 2023-06-07 09:24:59 -0700 | [diff] [blame] | 4109 |         [asyncResp, bootIndex, bootCount, entryCount, skip, | 
| Ed Tanous | 5e7e2dc | 2023-02-16 10:37:01 -0800 | [diff] [blame] | 4110 |          top](const boost::system::error_code& ec, | 
| Manojkiran Eda | 6c9a279 | 2021-02-27 14:25:04 +0530 | [diff] [blame] | 4111 |               const boost::container::flat_map< | 
 | 4112 |                   uint64_t, std::tuple<uint64_t, std::vector<uint8_t>>>& | 
 | 4113 |                   postcode) { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 4114 |         if (ec) | 
 | 4115 |         { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 4116 |             BMCWEB_LOG_DEBUG("DBUS POST CODE PostCode response error"); | 
| Ed Tanous | ac106bf | 2023-06-07 09:24:59 -0700 | [diff] [blame] | 4117 |             messages::internalError(asyncResp->res); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 4118 |             return; | 
 | 4119 |         } | 
| ZhikuiRen | a3316fc | 2020-01-29 14:58:08 -0800 | [diff] [blame] | 4120 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 4121 |         uint64_t endCount = entryCount; | 
 | 4122 |         if (!postcode.empty()) | 
 | 4123 |         { | 
 | 4124 |             endCount = entryCount + postcode.size(); | 
| Ed Tanous | 3648c8b | 2022-07-25 13:39:59 -0700 | [diff] [blame] | 4125 |             if (skip < endCount && (top + skip) > entryCount) | 
| ZhikuiRen | a3316fc | 2020-01-29 14:58:08 -0800 | [diff] [blame] | 4126 |             { | 
| Patrick Williams | 89492a1 | 2023-05-10 07:51:34 -0500 | [diff] [blame] | 4127 |                 uint64_t thisBootSkip = std::max(static_cast<uint64_t>(skip), | 
 | 4128 |                                                  entryCount) - | 
 | 4129 |                                         entryCount; | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 4130 |                 uint64_t thisBootTop = | 
| Ed Tanous | 3648c8b | 2022-07-25 13:39:59 -0700 | [diff] [blame] | 4131 |                     std::min(static_cast<uint64_t>(top + skip), endCount) - | 
 | 4132 |                     entryCount; | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 4133 |  | 
| Ed Tanous | ac106bf | 2023-06-07 09:24:59 -0700 | [diff] [blame] | 4134 |                 fillPostCodeEntry(asyncResp, postcode, bootIndex, 0, | 
 | 4135 |                                   thisBootSkip, thisBootTop); | 
| ZhikuiRen | a3316fc | 2020-01-29 14:58:08 -0800 | [diff] [blame] | 4136 |             } | 
| Ed Tanous | ac106bf | 2023-06-07 09:24:59 -0700 | [diff] [blame] | 4137 |             asyncResp->res.jsonValue["Members@odata.count"] = endCount; | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 4138 |         } | 
 | 4139 |  | 
 | 4140 |         // continue to previous bootIndex | 
 | 4141 |         if (bootIndex < bootCount) | 
 | 4142 |         { | 
| Ed Tanous | ac106bf | 2023-06-07 09:24:59 -0700 | [diff] [blame] | 4143 |             getPostCodeForBoot(asyncResp, static_cast<uint16_t>(bootIndex + 1), | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 4144 |                                bootCount, endCount, skip, top); | 
 | 4145 |         } | 
| Jiaqing Zhao | 81584ab | 2022-07-28 00:33:45 +0800 | [diff] [blame] | 4146 |         else if (skip + top < endCount) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 4147 |         { | 
| Ed Tanous | ac106bf | 2023-06-07 09:24:59 -0700 | [diff] [blame] | 4148 |             asyncResp->res.jsonValue["Members@odata.nextLink"] = | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 4149 |                 "/redfish/v1/Systems/system/LogServices/PostCodes/Entries?$skip=" + | 
 | 4150 |                 std::to_string(skip + top); | 
 | 4151 |         } | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 4152 |     }, | 
| Jonathan Doman | 1512476 | 2021-01-07 17:54:17 -0800 | [diff] [blame] | 4153 |         "xyz.openbmc_project.State.Boot.PostCode0", | 
 | 4154 |         "/xyz/openbmc_project/State/Boot/PostCode0", | 
| ZhikuiRen | a3316fc | 2020-01-29 14:58:08 -0800 | [diff] [blame] | 4155 |         "xyz.openbmc_project.State.Boot.PostCode", "GetPostCodesWithTimeStamp", | 
 | 4156 |         bootIndex); | 
 | 4157 | } | 
 | 4158 |  | 
| zhanghch05 | 8d1b46d | 2021-04-01 11:18:24 +0800 | [diff] [blame] | 4159 | static void | 
| Ed Tanous | ac106bf | 2023-06-07 09:24:59 -0700 | [diff] [blame] | 4160 |     getCurrentBootNumber(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
| Ed Tanous | 3648c8b | 2022-07-25 13:39:59 -0700 | [diff] [blame] | 4161 |                          size_t skip, size_t top) | 
| ZhikuiRen | a3316fc | 2020-01-29 14:58:08 -0800 | [diff] [blame] | 4162 | { | 
 | 4163 |     uint64_t entryCount = 0; | 
| Jonathan Doman | 1e1e598 | 2021-06-11 09:36:17 -0700 | [diff] [blame] | 4164 |     sdbusplus::asio::getProperty<uint16_t>( | 
 | 4165 |         *crow::connections::systemBus, | 
 | 4166 |         "xyz.openbmc_project.State.Boot.PostCode0", | 
 | 4167 |         "/xyz/openbmc_project/State/Boot/PostCode0", | 
 | 4168 |         "xyz.openbmc_project.State.Boot.PostCode", "CurrentBootCycleCount", | 
| Ed Tanous | ac106bf | 2023-06-07 09:24:59 -0700 | [diff] [blame] | 4169 |         [asyncResp, entryCount, skip, top](const boost::system::error_code& ec, | 
 | 4170 |                                            const uint16_t bootCount) { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 4171 |         if (ec) | 
 | 4172 |         { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 4173 |             BMCWEB_LOG_DEBUG("DBUS response error {}", ec); | 
| Ed Tanous | ac106bf | 2023-06-07 09:24:59 -0700 | [diff] [blame] | 4174 |             messages::internalError(asyncResp->res); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 4175 |             return; | 
 | 4176 |         } | 
| Ed Tanous | ac106bf | 2023-06-07 09:24:59 -0700 | [diff] [blame] | 4177 |         getPostCodeForBoot(asyncResp, 1, bootCount, entryCount, skip, top); | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 4178 |     }); | 
| ZhikuiRen | a3316fc | 2020-01-29 14:58:08 -0800 | [diff] [blame] | 4179 | } | 
 | 4180 |  | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 4181 | inline void requestRoutesPostCodesEntryCollection(App& app) | 
| ZhikuiRen | a3316fc | 2020-01-29 14:58:08 -0800 | [diff] [blame] | 4182 | { | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 4183 |     BMCWEB_ROUTE(app, | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 4184 |                  "/redfish/v1/Systems/<str>/LogServices/PostCodes/Entries/") | 
| Ed Tanous | ed39821 | 2021-06-09 17:05:54 -0700 | [diff] [blame] | 4185 |         .privileges(redfish::privileges::getLogEntryCollection) | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 4186 |         .methods(boost::beast::http::verb::get)( | 
| Ed Tanous | 45ca1b8 | 2022-03-25 13:07:27 -0700 | [diff] [blame] | 4187 |             [&app](const crow::Request& req, | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 4188 |                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 4189 |                    const std::string& systemName) { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 4190 |         query_param::QueryCapabilities capabilities = { | 
 | 4191 |             .canDelegateTop = true, | 
 | 4192 |             .canDelegateSkip = true, | 
 | 4193 |         }; | 
 | 4194 |         query_param::Query delegatedQuery; | 
 | 4195 |         if (!redfish::setUpRedfishRouteWithDelegation( | 
| Carson Labrado | 3ba0007 | 2022-06-06 19:40:56 +0000 | [diff] [blame] | 4196 |                 app, req, asyncResp, delegatedQuery, capabilities)) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 4197 |         { | 
 | 4198 |             return; | 
 | 4199 |         } | 
| Ed Tanous | 7f3e84a | 2022-12-28 16:22:54 -0800 | [diff] [blame] | 4200 |         if constexpr (bmcwebEnableMultiHost) | 
 | 4201 |         { | 
 | 4202 |             // Option currently returns no systems.  TBD | 
 | 4203 |             messages::resourceNotFound(asyncResp->res, "ComputerSystem", | 
 | 4204 |                                        systemName); | 
 | 4205 |             return; | 
 | 4206 |         } | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 4207 |  | 
 | 4208 |         if (systemName != "system") | 
 | 4209 |         { | 
 | 4210 |             messages::resourceNotFound(asyncResp->res, "ComputerSystem", | 
 | 4211 |                                        systemName); | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 4212 |             return; | 
 | 4213 |         } | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 4214 |         asyncResp->res.jsonValue["@odata.type"] = | 
 | 4215 |             "#LogEntryCollection.LogEntryCollection"; | 
 | 4216 |         asyncResp->res.jsonValue["@odata.id"] = | 
 | 4217 |             "/redfish/v1/Systems/system/LogServices/PostCodes/Entries"; | 
 | 4218 |         asyncResp->res.jsonValue["Name"] = "BIOS POST Code Log Entries"; | 
 | 4219 |         asyncResp->res.jsonValue["Description"] = | 
 | 4220 |             "Collection of POST Code Log Entries"; | 
 | 4221 |         asyncResp->res.jsonValue["Members"] = nlohmann::json::array(); | 
 | 4222 |         asyncResp->res.jsonValue["Members@odata.count"] = 0; | 
| Ed Tanous | 3648c8b | 2022-07-25 13:39:59 -0700 | [diff] [blame] | 4223 |         size_t skip = delegatedQuery.skip.value_or(0); | 
| Jiaqing Zhao | 5143f7a | 2022-07-22 09:33:33 +0800 | [diff] [blame] | 4224 |         size_t top = delegatedQuery.top.value_or(query_param::Query::maxTop); | 
| Ed Tanous | 3648c8b | 2022-07-25 13:39:59 -0700 | [diff] [blame] | 4225 |         getCurrentBootNumber(asyncResp, skip, top); | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 4226 |     }); | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 4227 | } | 
| ZhikuiRen | a3316fc | 2020-01-29 14:58:08 -0800 | [diff] [blame] | 4228 |  | 
| George Liu | 647b3cd | 2021-07-05 12:43:56 +0800 | [diff] [blame] | 4229 | inline void requestRoutesPostCodesEntryAdditionalData(App& app) | 
 | 4230 | { | 
| George Liu | 0fda0f1 | 2021-11-16 10:06:17 +0800 | [diff] [blame] | 4231 |     BMCWEB_ROUTE( | 
 | 4232 |         app, | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 4233 |         "/redfish/v1/Systems/<str>/LogServices/PostCodes/Entries/<str>/attachment/") | 
| George Liu | 647b3cd | 2021-07-05 12:43:56 +0800 | [diff] [blame] | 4234 |         .privileges(redfish::privileges::getLogEntry) | 
 | 4235 |         .methods(boost::beast::http::verb::get)( | 
| Ed Tanous | 45ca1b8 | 2022-03-25 13:07:27 -0700 | [diff] [blame] | 4236 |             [&app](const crow::Request& req, | 
 | 4237 |                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 4238 |                    const std::string& systemName, | 
| Ed Tanous | 45ca1b8 | 2022-03-25 13:07:27 -0700 | [diff] [blame] | 4239 |                    const std::string& postCodeID) { | 
| Carson Labrado | 3ba0007 | 2022-06-06 19:40:56 +0000 | [diff] [blame] | 4240 |         if (!redfish::setUpRedfishRoute(app, req, asyncResp)) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 4241 |         { | 
 | 4242 |             return; | 
 | 4243 |         } | 
| Matt Spinler | 72e2137 | 2023-04-19 12:53:33 -0500 | [diff] [blame] | 4244 |         if (!http_helpers::isContentTypeAllowed( | 
| Ed Tanous | 99351cd | 2022-08-07 16:42:51 -0700 | [diff] [blame] | 4245 |                 req.getHeaderValue("Accept"), | 
| Ed Tanous | 4a0e1a0 | 2022-09-21 15:28:04 -0700 | [diff] [blame] | 4246 |                 http_helpers::ContentType::OctetStream, true)) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 4247 |         { | 
 | 4248 |             asyncResp->res.result(boost::beast::http::status::bad_request); | 
 | 4249 |             return; | 
 | 4250 |         } | 
| Ed Tanous | 7f3e84a | 2022-12-28 16:22:54 -0800 | [diff] [blame] | 4251 |         if constexpr (bmcwebEnableMultiHost) | 
 | 4252 |         { | 
 | 4253 |             // Option currently returns no systems.  TBD | 
 | 4254 |             messages::resourceNotFound(asyncResp->res, "ComputerSystem", | 
 | 4255 |                                        systemName); | 
 | 4256 |             return; | 
 | 4257 |         } | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 4258 |         if (systemName != "system") | 
 | 4259 |         { | 
 | 4260 |             messages::resourceNotFound(asyncResp->res, "ComputerSystem", | 
 | 4261 |                                        systemName); | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 4262 |             return; | 
 | 4263 |         } | 
| George Liu | 647b3cd | 2021-07-05 12:43:56 +0800 | [diff] [blame] | 4264 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 4265 |         uint64_t currentValue = 0; | 
 | 4266 |         uint16_t index = 0; | 
 | 4267 |         if (!parsePostCode(postCodeID, currentValue, index)) | 
 | 4268 |         { | 
 | 4269 |             messages::resourceNotFound(asyncResp->res, "LogEntry", postCodeID); | 
 | 4270 |             return; | 
 | 4271 |         } | 
| George Liu | 647b3cd | 2021-07-05 12:43:56 +0800 | [diff] [blame] | 4272 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 4273 |         crow::connections::systemBus->async_method_call( | 
 | 4274 |             [asyncResp, postCodeID, currentValue]( | 
| Ed Tanous | 5e7e2dc | 2023-02-16 10:37:01 -0800 | [diff] [blame] | 4275 |                 const boost::system::error_code& ec, | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 4276 |                 const std::vector<std::tuple<uint64_t, std::vector<uint8_t>>>& | 
 | 4277 |                     postcodes) { | 
 | 4278 |             if (ec.value() == EBADR) | 
 | 4279 |             { | 
 | 4280 |                 messages::resourceNotFound(asyncResp->res, "LogEntry", | 
 | 4281 |                                            postCodeID); | 
 | 4282 |                 return; | 
 | 4283 |             } | 
 | 4284 |             if (ec) | 
 | 4285 |             { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 4286 |                 BMCWEB_LOG_DEBUG("DBUS response error {}", ec); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 4287 |                 messages::internalError(asyncResp->res); | 
 | 4288 |                 return; | 
 | 4289 |             } | 
| George Liu | 647b3cd | 2021-07-05 12:43:56 +0800 | [diff] [blame] | 4290 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 4291 |             size_t value = static_cast<size_t>(currentValue) - 1; | 
 | 4292 |             if (value == std::string::npos || postcodes.size() < currentValue) | 
 | 4293 |             { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 4294 |                 BMCWEB_LOG_WARNING("Wrong currentValue value"); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 4295 |                 messages::resourceNotFound(asyncResp->res, "LogEntry", | 
 | 4296 |                                            postCodeID); | 
 | 4297 |                 return; | 
 | 4298 |             } | 
| George Liu | 647b3cd | 2021-07-05 12:43:56 +0800 | [diff] [blame] | 4299 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 4300 |             const auto& [tID, c] = postcodes[value]; | 
 | 4301 |             if (c.empty()) | 
 | 4302 |             { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 4303 |                 BMCWEB_LOG_WARNING("No found post code data"); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 4304 |                 messages::resourceNotFound(asyncResp->res, "LogEntry", | 
 | 4305 |                                            postCodeID); | 
 | 4306 |                 return; | 
 | 4307 |             } | 
 | 4308 |             // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) | 
 | 4309 |             const char* d = reinterpret_cast<const char*>(c.data()); | 
 | 4310 |             std::string_view strData(d, c.size()); | 
| George Liu | 647b3cd | 2021-07-05 12:43:56 +0800 | [diff] [blame] | 4311 |  | 
| Ed Tanous | d9f6c62 | 2022-03-17 09:12:17 -0700 | [diff] [blame] | 4312 |             asyncResp->res.addHeader(boost::beast::http::field::content_type, | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 4313 |                                      "application/octet-stream"); | 
| Ed Tanous | d9f6c62 | 2022-03-17 09:12:17 -0700 | [diff] [blame] | 4314 |             asyncResp->res.addHeader( | 
 | 4315 |                 boost::beast::http::field::content_transfer_encoding, "Base64"); | 
| Ed Tanous | 27b0cf9 | 2023-08-07 12:02:40 -0700 | [diff] [blame] | 4316 |             asyncResp->res.write(crow::utility::base64encode(strData)); | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 4317 |         }, | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 4318 |             "xyz.openbmc_project.State.Boot.PostCode0", | 
 | 4319 |             "/xyz/openbmc_project/State/Boot/PostCode0", | 
 | 4320 |             "xyz.openbmc_project.State.Boot.PostCode", "GetPostCodes", index); | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 4321 |     }); | 
| George Liu | 647b3cd | 2021-07-05 12:43:56 +0800 | [diff] [blame] | 4322 | } | 
 | 4323 |  | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 4324 | inline void requestRoutesPostCodesEntry(App& app) | 
| ZhikuiRen | a3316fc | 2020-01-29 14:58:08 -0800 | [diff] [blame] | 4325 | { | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 4326 |     BMCWEB_ROUTE( | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 4327 |         app, "/redfish/v1/Systems/<str>/LogServices/PostCodes/Entries/<str>/") | 
| Ed Tanous | ed39821 | 2021-06-09 17:05:54 -0700 | [diff] [blame] | 4328 |         .privileges(redfish::privileges::getLogEntry) | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 4329 |         .methods(boost::beast::http::verb::get)( | 
| Ed Tanous | 45ca1b8 | 2022-03-25 13:07:27 -0700 | [diff] [blame] | 4330 |             [&app](const crow::Request& req, | 
 | 4331 |                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 4332 |                    const std::string& systemName, const std::string& targetID) { | 
| Carson Labrado | 3ba0007 | 2022-06-06 19:40:56 +0000 | [diff] [blame] | 4333 |         if (!redfish::setUpRedfishRoute(app, req, asyncResp)) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 4334 |         { | 
 | 4335 |             return; | 
 | 4336 |         } | 
| Ed Tanous | 7f3e84a | 2022-12-28 16:22:54 -0800 | [diff] [blame] | 4337 |         if constexpr (bmcwebEnableMultiHost) | 
 | 4338 |         { | 
 | 4339 |             // Option currently returns no systems.  TBD | 
 | 4340 |             messages::resourceNotFound(asyncResp->res, "ComputerSystem", | 
 | 4341 |                                        systemName); | 
 | 4342 |             return; | 
 | 4343 |         } | 
| Ed Tanous | 22d268c | 2022-05-19 09:39:07 -0700 | [diff] [blame] | 4344 |         if (systemName != "system") | 
 | 4345 |         { | 
 | 4346 |             messages::resourceNotFound(asyncResp->res, "ComputerSystem", | 
 | 4347 |                                        systemName); | 
 | 4348 |             return; | 
 | 4349 |         } | 
 | 4350 |  | 
| Jiaqing Zhao | 6f284d2 | 2022-10-10 15:56:45 +0800 | [diff] [blame] | 4351 |         getPostCodeForEntry(asyncResp, targetID); | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 4352 |     }); | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 4353 | } | 
| ZhikuiRen | a3316fc | 2020-01-29 14:58:08 -0800 | [diff] [blame] | 4354 |  | 
| Ed Tanous | 1da66f7 | 2018-07-27 16:13:37 -0700 | [diff] [blame] | 4355 | } // namespace redfish |