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