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)164std::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