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