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