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