blob: 0be63fc64ceef5512bf2e6d2aa8b89478f316ae8 [file] [log] [blame]
Jason M. Bills5e049d32018-10-19 12:59:38 -07001/*
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
17#pragma once
Lei YU9916d412025-02-06 11:51:18 +000018#include <sdbusplus/asio/connection.hpp>
19
Jason M. Billsc4a336f2019-04-23 10:43:10 -070020#include <filesystem>
Lei YU9916d412025-02-06 11:51:18 +000021#include <string>
Jason M. Bills5e049d32018-10-19 12:59:38 -070022
Patrick Williams69f7fa32023-05-10 07:50:41 -050023static constexpr const char* ipmiSelObject = "xyz.openbmc_project.Logging.IPMI";
24static constexpr const char* ipmiSelPath = "/xyz/openbmc_project/Logging/IPMI";
25static constexpr const char* ipmiSelAddInterface =
Jason M. Bills5e049d32018-10-19 12:59:38 -070026 "xyz.openbmc_project.Logging.IPMI";
27
28// ID string generated using journalctl to include in the MESSAGE_ID field for
29// SEL entries. Helps with filtering SEL entries in the journal.
Patrick Williams69f7fa32023-05-10 07:50:41 -050030static constexpr const char* selMessageId = "b370836ccf2f4850ac5bee185b77893a";
Jason M. Bills5e049d32018-10-19 12:59:38 -070031static constexpr int selPriority = 5; // notice
32static constexpr uint8_t selSystemType = 0x02;
33static constexpr uint16_t selBMCGenID = 0x0020;
34static constexpr uint16_t selInvalidRecID =
35 std::numeric_limits<uint16_t>::max();
36static constexpr size_t selEvtDataMaxSize = 3;
37static constexpr size_t selOemDataMaxSize = 13;
Zhikui Ren25b26e12020-06-26 20:18:19 -070038static constexpr uint8_t selEvtDataUnspecified = 0xFF;
Jason M. Bills5e049d32018-10-19 12:59:38 -070039
Jason M. Billsc4a336f2019-04-23 10:43:10 -070040static const std::filesystem::path selLogDir = "/var/log";
41static const std::string selLogFilename = "ipmi_sel";
Jonico Eustaquio9fa224c2024-01-10 13:08:52 -060042#ifdef SEL_LOGGER_ENABLE_SEL_DELETE
43static const std::string nextRecordFilename = "next_records";
44#endif
Jason M. Billsc4a336f2019-04-23 10:43:10 -070045
Lei YU9916d412025-02-06 11:51:18 +000046void toHexStr(const std::vector<uint8_t>& data, std::string& hexStr);
47
Jason M. Bills97be3532018-11-02 13:09:16 -070048template <typename... T>
Lei YU9916d412025-02-06 11:51:18 +000049uint16_t selAddSystemRecord(
50 [[maybe_unused]] std::shared_ptr<sdbusplus::asio::connection> conn,
51 [[maybe_unused]] const std::string& message, const std::string& path,
Patrick Williamsa58ea682025-02-01 08:22:21 -050052 const std::vector<uint8_t>& selData, const bool& assert,
Lei YU9916d412025-02-06 11:51:18 +000053 const uint16_t& genId, [[maybe_unused]] T&&... metadata)
54{
55 // Only 3 bytes of SEL event data are allowed in a system record
56 if (selData.size() > selEvtDataMaxSize)
57 {
58 throw std::invalid_argument("Event data too large");
59 }
60 std::string selDataStr;
61 toHexStr(selData, selDataStr);
62
63#ifdef SEL_LOGGER_SEND_TO_LOGGING_SERVICE
64 sdbusplus::message_t AddToLog = conn->new_method_call(
65 "xyz.openbmc_project.Logging", "/xyz/openbmc_project/logging",
66 "xyz.openbmc_project.Logging.Create", "Create");
67
68 std::string journalMsg(
69 message + " from " + path + ": " +
70 " RecordType=" + std::to_string(selSystemType) +
71 ", GeneratorID=" + std::to_string(genId) +
72 ", EventDir=" + std::to_string(assert) + ", EventData=" + selDataStr);
73
74 AddToLog.append(
75 journalMsg, "xyz.openbmc_project.Logging.Entry.Level.Informational",
76 std::map<std::string, std::string>(
77 {{"SENSOR_PATH", path},
78 {"GENERATOR_ID", std::to_string(genId)},
79 {"RECORD_TYPE", std::to_string(selSystemType)},
80 {"EVENT_DIR", std::to_string(assert)},
81 {"SENSOR_DATA", selDataStr}}));
82 conn->call(AddToLog);
83 return 0;
84#else
85 unsigned int recordId = getNewRecordId();
86 if (recordId < selInvalidRecID)
87 {
88 sd_journal_send(
89 "MESSAGE=%s", message.c_str(), "PRIORITY=%i", selPriority,
90 "MESSAGE_ID=%s", selMessageId, "IPMI_SEL_RECORD_ID=%d", recordId,
91 "IPMI_SEL_RECORD_TYPE=%x", selSystemType,
92 "IPMI_SEL_GENERATOR_ID=%x", genId, "IPMI_SEL_SENSOR_PATH=%s",
93 path.c_str(), "IPMI_SEL_EVENT_DIR=%x", assert, "IPMI_SEL_DATA=%s",
94 selDataStr.c_str(), std::forward<T>(metadata)..., NULL);
95 }
96 return recordId;
97#endif
98}