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