summaryrefslogtreecommitdiff
path: root/redfish-core/lib/log_services.hpp
diff options
context:
space:
mode:
authorGeorge Liu <liuxiwei@inspur.com>2021-03-08 14:36:32 +0300
committerGeorge Liu <liuxiwei@inspur.com>2021-06-30 03:41:28 +0300
commitaf61db10fb40c7beb91a70f0b3ff28cb8e6c1704 (patch)
treefca36609e73134af0f36fda7e4649a32bd9b59bd /redfish-core/lib/log_services.hpp
parent0ef217f4e89016e8f49f487fe65934b934aab077 (diff)
downloadbmcweb-af61db10fb40c7beb91a70f0b3ff28cb8e6c1704.tar.xz
log_services: Add download of post code log entries
- Add a GET method /redfish/v1/Systems/system/LogServices/PostCodes /Entries/<str>/attachment/, Get the attribute value through the getPostCodes method and encode it as base64, and send it off. - This allows the use to offload error logs for analysis and further parsing if needed. An http header of "Accept: application/octet-stream" or the default "*/*" is expected. Tested: - Ran Redfish validator. - pldmtool raw --data 0x80 0x3F 0xC 0x0A 0x00 0x00 0x00 0x00 0x00 0x07 0x00 0x00 0x00 0x48 0x00 0x00 0x00 0x02 0x00 0x00 0x01 0x00 0x00 0x00 0x48 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x53 0x54 0x41 0x4e 0x44 0x42 0x59 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20 $curl -k https://127.0.0.1:2443/redfish/v1/Systems/system/LogServices/PostCodes/Entries/B1-1/attachment/ output: AgAAAQAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFNUQU5EQlkgICAgICAgICAgICAgICAgICAgICAgICAg Signed-off-by: George Liu <liuxiwei@inspur.com> Change-Id: I74dd6c1dc2d3dfb7908f7741e0d9e7825c1df816
Diffstat (limited to 'redfish-core/lib/log_services.hpp')
-rw-r--r--redfish-core/lib/log_services.hpp132
1 files changed, 114 insertions, 18 deletions
diff --git a/redfish-core/lib/log_services.hpp b/redfish-core/lib/log_services.hpp
index 8a6853451e..2b064146e9 100644
--- a/redfish-core/lib/log_services.hpp
+++ b/redfish-core/lib/log_services.hpp
@@ -15,6 +15,7 @@
*/
#pragma once
+#include "http_utility.hpp"
#include "registries.hpp"
#include "registries/base_message_registry.hpp"
#include "registries/openbmc_message_registry.hpp"
@@ -32,6 +33,7 @@
#include <boost/system/linux_error.hpp>
#include <error_messages.hpp>
+#include <charconv>
#include <filesystem>
#include <optional>
#include <string_view>
@@ -1691,24 +1693,7 @@ inline void requestRoutesDBusEventLogEntryDownload(App& app)
const std::string& param)
{
- std::string_view acceptHeader = req.getHeaderValue("Accept");
- // The iterators in boost/http/rfc7230.hpp end the string if '/'
- // is found, so replace it with arbitrary character '|' which is
- // not part of the Accept header syntax.
- std::string acceptStr = boost::replace_all_copy(
- std::string(acceptHeader), "/", "|");
- boost::beast::http::ext_list acceptTypes{acceptStr};
- bool supported = false;
- for (const auto& type : acceptTypes)
- {
- if ((type.first == "*|*") ||
- (type.first == "application|octet-stream"))
- {
- supported = true;
- break;
- }
- }
- if (!supported)
+ if (!http_helpers::isOctetAccepted(req))
{
asyncResp->res.result(
boost::beast::http::status::bad_request);
@@ -3032,6 +3017,117 @@ static void
"xyz.openbmc_project.State.Boot.PostCode", "CurrentBootCycleCount");
}
+inline static bool parsePostCode(std::string postCodeID, uint64_t& currentValue,
+ uint16_t& index)
+{
+ // postCodeID = B1-1
+ std::vector<std::string> split;
+ boost::algorithm::split(split, postCodeID, boost::is_any_of("-"));
+ if (split.size() != 2 || split[0].length() < 2)
+ {
+ return false;
+ }
+
+ const char* start = split[0].data() + 1;
+ const char* end = split[0].data() + split[0].size();
+ auto [ptrIndex, ecIndex] = std::from_chars(start, end, index);
+
+ if (ptrIndex != end || ecIndex != std::errc() || !index)
+ {
+ return false;
+ }
+
+ start = split[1].data();
+ end = split[1].data() + split[1].size();
+ auto [ptrValue, ecValue] = std::from_chars(start, end, currentValue);
+ if (ptrValue != end || ecValue != std::errc() || !currentValue)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+inline void requestRoutesPostCodesEntryAdditionalData(App& app)
+{
+ BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/LogServices/PostCodes/"
+ "Entries/<str>/attachment/")
+ .privileges({"Login"})
+ .methods(boost::beast::http::verb::get)(
+ [](const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& postCodeID) {
+ if (!http_helpers::isOctetAccepted(req))
+ {
+ asyncResp->res.result(
+ boost::beast::http::status::bad_request);
+ return;
+ }
+
+ uint64_t currentValue = 0;
+ uint16_t index = 0;
+ if (!parsePostCode(postCodeID, currentValue, index))
+ {
+ messages::resourceNotFound(asyncResp->res, "LogEntry",
+ postCodeID);
+ return;
+ }
+
+ crow::connections::systemBus->async_method_call(
+ [asyncResp, postCodeID, currentValue](
+ const boost::system::error_code ec,
+ const std::vector<std::tuple<
+ uint64_t, std::vector<uint8_t>>>& postcodes) {
+ if (ec.value() == EBADR)
+ {
+ messages::resourceNotFound(asyncResp->res,
+ "LogEntry", postCodeID);
+ return;
+ }
+ if (ec)
+ {
+ BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
+ messages::internalError(asyncResp->res);
+ return;
+ }
+
+ if (currentValue < 1 ||
+ postcodes.size() <= currentValue)
+ {
+ BMCWEB_LOG_ERROR << "Wrong currentValue value";
+ messages::resourceNotFound(asyncResp->res,
+ "LogEntry", postCodeID);
+ return;
+ }
+
+ size_t value = static_cast<size_t>(currentValue) - 1;
+ auto& [tID, code] = postcodes[value];
+
+ if (code.size() == 0)
+ {
+ BMCWEB_LOG_INFO << "No found post code data";
+ messages::internalError(asyncResp->res);
+ return;
+ }
+
+ std::string_view strData(
+ reinterpret_cast<const char*>(code.data()),
+ code.size());
+
+ asyncResp->res.addHeader("Content-Type",
+ "application/octet-stream");
+ asyncResp->res.addHeader("Content-Transfer-Encoding",
+ "Base64");
+ asyncResp->res.body() =
+ std::move(crow::utility::base64encode(strData));
+ },
+ "xyz.openbmc_project.State.Boot.PostCode0",
+ "/xyz/openbmc_project/State/Boot/PostCode0",
+ "xyz.openbmc_project.State.Boot.PostCode", "GetPostCodes",
+ index);
+ });
+}
+
inline void requestRoutesPostCodesEntryCollection(App& app)
{
BMCWEB_ROUTE(app,