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