-
Notifications
You must be signed in to change notification settings - Fork 75
/
selutility.hpp
210 lines (178 loc) · 6.25 KB
/
selutility.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
#pragma once
#include <ipmid/types.hpp>
#include <sdbusplus/server.hpp>
#include <chrono>
#include <cstdint>
#include <iomanip>
#include <iostream>
#include <sstream>
namespace ipmi
{
namespace sel
{
static constexpr auto mapperBusName = "xyz.openbmc_project.ObjectMapper";
static constexpr auto mapperObjPath = "/xyz/openbmc_project/object_mapper";
static constexpr auto mapperIntf = "xyz.openbmc_project.ObjectMapper";
static constexpr auto logWatchPath = "/xyz/openbmc_project/logging";
static constexpr auto logBasePath = "/xyz/openbmc_project/logging/entry";
static constexpr auto logEntryIntf = "xyz.openbmc_project.Logging.Entry";
static constexpr auto logDeleteIntf = "xyz.openbmc_project.Object.Delete";
static constexpr auto logObj = "/xyz/openbmc_project/logging";
static constexpr auto logIntf = "xyz.openbmc_project.Collection.DeleteAll";
static constexpr auto logDeleteAllMethod = "DeleteAll";
static constexpr auto propIntf = "org.freedesktop.DBus.Properties";
using ObjectPaths = std::vector<std::string>;
using PropertyName = std::string;
using Resolved = bool;
using Id = uint32_t;
using Timestamp = uint64_t;
using Message = std::string;
using AdditionalData = std::vector<std::string>;
using PropertyType =
std::variant<Resolved, Id, Timestamp, Message, AdditionalData>;
static constexpr auto selVersion = 0x51;
static constexpr auto invalidTimeStamp = 0xFFFFFFFF;
static constexpr auto firstEntry = 0x0000;
static constexpr auto lastEntry = 0xFFFF;
static constexpr auto entireRecord = 0xFF;
static constexpr auto selRecordSize = 16;
namespace operationSupport
{
static constexpr bool overflow = false;
static constexpr bool deleteSel = true;
static constexpr bool partialAddSelEntry = false;
static constexpr bool reserveSel = true;
static constexpr bool getSelAllocationInfo = false;
} // namespace operationSupport
/** @struct GetSELEntryRequest
*
* IPMI payload for Get SEL Entry command request.
*/
struct GetSELEntryRequest
{
uint16_t reservationID; //!< Reservation ID.
uint16_t selRecordID; //!< SEL Record ID.
uint8_t offset; //!< Offset into record.
uint8_t readLength; //!< Bytes to read.
} __attribute__((packed));
constexpr size_t SELRecordLength = 16;
/** @struct SELEventRecord
*
* IPMI SEL Event Record
*/
struct SELEventRecord
{
uint16_t recordID; //!< Record ID.
uint8_t recordType; //!< Record Type.
uint32_t timeStamp; //!< Timestamp.
uint16_t generatorID; //!< Generator ID.
uint8_t eventMsgRevision; //!< Event Message Revision.
uint8_t sensorType; //!< Sensor Type.
uint8_t sensorNum; //!< Sensor Number.
uint8_t eventType; //!< Event Dir | Event Type.
uint8_t eventData1; //!< Event Data 1.
uint8_t eventData2; //!< Event Data 2.
uint8_t eventData3; //!< Event Data 3.
} __attribute__((packed));
static_assert(sizeof(SELEventRecord) == SELRecordLength);
/** @struct SELOEMRecordTypeCD
*
* IPMI SEL OEM Record - Type C0h-DFh
*/
struct SELOEMRecordTypeCD
{
uint16_t recordID; //!< Record ID.
uint8_t recordType; //!< Record Type.
uint32_t timeStamp; //!< Timestamp.
uint8_t manufacturerID[3]; //!< Manufacturer ID.
uint8_t oemDefined[6]; //!< OEM Defined data.
} __attribute__((packed));
static_assert(sizeof(SELOEMRecordTypeCD) == SELRecordLength);
/** @struct SELOEMRecordTypeEF
*
* IPMI SEL OEM Record - Type E0h-FFh
*/
struct SELOEMRecordTypeEF
{
uint16_t recordID; //!< Record ID.
uint8_t recordType; //!< Record Type.
uint8_t oemDefined[13]; //!< OEM Defined data.
} __attribute__((packed));
static_assert(sizeof(SELOEMRecordTypeEF) == SELRecordLength);
union SELEventRecordFormat
{
SELEventRecord eventRecord;
SELOEMRecordTypeCD oemCD;
SELOEMRecordTypeEF oemEF;
};
/** @struct GetSELEntryResponse
*
* IPMI payload for Get SEL Entry command response.
*/
struct GetSELEntryResponse
{
uint16_t nextRecordID; //!< Next RecordID.
SELEventRecordFormat event; // !< The Event Record.
} __attribute__((packed));
static_assert(sizeof(GetSELEntryResponse) ==
SELRecordLength + sizeof(uint16_t));
static constexpr auto initiateErase = 0xAA;
static constexpr auto getEraseStatus = 0x00;
static constexpr auto eraseComplete = 0x01;
/** @brief Convert logging entry to SEL
*
* @param[in] objPath - DBUS object path of the logging entry.
*
* @return On success return the response of Get SEL entry command.
*/
GetSELEntryResponse convertLogEntrytoSEL(const std::string& objPath);
/** @brief Get the timestamp of the log entry
*
* @param[in] objPath - DBUS object path of the logging entry.
*
* @return On success return the timestamp of the log entry as number of
* seconds from epoch.
*/
std::chrono::seconds getEntryTimeStamp(const std::string& objPath);
/** @brief Read the logging entry object paths
*
* This API would read the logging dbus logging entry object paths and sorting
* the filename in the numeric order. The paths is cleared before populating
* the object paths.
*
* @param[in,out] paths - sorted list of logging entry object paths.
*
* @note This function is invoked when the Get SEL Info command or the Delete
* SEL entry command is invoked. The Get SEL Entry command is preceded
* typically by Get SEL Info command, so readLoggingObjectPaths is not
* invoked before each Get SEL entry command.
*/
void readLoggingObjectPaths(ObjectPaths& paths);
template <typename T>
std::string toHexStr(const T& data)
{
std::stringstream stream;
stream << std::hex << std::uppercase << std::setfill('0');
for (const auto& v : data)
{
stream << std::setw(2) << static_cast<int>(v);
}
return stream.str();
}
namespace internal
{
/** @brief Convert logging entry to SEL event record
*
* @param[in] objPath - DBUS object path of the logging entry.
* @param[in] iter - Iterator to the sensor data corresponding to the logging
* entry
*
* @return On success return the SEL event record, throw an exception in case
* of failure.
*/
GetSELEntryResponse
prepareSELEntry(const std::string& objPath,
ipmi::sensor::InvObjectIDMap::const_iterator iter);
} // namespace internal
} // namespace sel
} // namespace ipmi