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