1 #pragma once 2 3 #include "libpldm/fru.h" 4 #include "libpldm/platform.h" 5 6 #include "common/types.hpp" 7 #include "dbus_impl_fru.hpp" 8 #include "numeric_sensor.hpp" 9 #include "requester/handler.hpp" 10 #include "terminus.hpp" 11 12 #include <sdbusplus/server/object.hpp> 13 #include <sdeventplus/event.hpp> 14 15 #include <algorithm> 16 #include <bitset> 17 #include <string> 18 #include <tuple> 19 #include <utility> 20 #include <vector> 21 22 namespace pldm 23 { 24 namespace platform_mc 25 { 26 27 using ContainerID = uint16_t; 28 using EntityInstanceNumber = uint16_t; 29 using EntityName = std::string; 30 using EntityType = uint16_t; 31 using SensorId = uint16_t; 32 using SensorCnt = uint8_t; 33 using NameLanguageTag = std::string; 34 using SensorName = std::string; 35 using SensorAuxiliaryNames = std::tuple< 36 SensorId, SensorCnt, 37 std::vector<std::vector<std::pair<NameLanguageTag, SensorName>>>>; 38 39 /** @struct EntityKey 40 * 41 * EntityKey uniquely identifies the PLDM entity and a combination of Entity 42 * Type, Entity Instance Number, Entity Container ID 43 * 44 */ 45 struct EntityKey 46 { 47 EntityType type; //!< Entity type 48 EntityInstanceNumber instanceIdx; //!< Entity instance number 49 ContainerID containerId; //!< Entity container ID 50 operator ==pldm::platform_mc::EntityKey51 bool operator==(const EntityKey& e) const 52 { 53 return ((type == e.type) && (instanceIdx == e.instanceIdx) && 54 (containerId == e.containerId)); 55 } 56 }; 57 58 using AuxiliaryNames = std::vector<std::pair<NameLanguageTag, std::string>>; 59 using EntityKey = struct EntityKey; 60 using EntityAuxiliaryNames = std::tuple<EntityKey, AuxiliaryNames>; 61 62 /** 63 * @brief Terminus 64 * 65 * Terminus class holds the TID, supported PLDM Type or PDRs which are needed by 66 * other manager class for sensor monitoring and control. 67 */ 68 class Terminus 69 { 70 public: 71 Terminus(pldm_tid_t tid, uint64_t supportedPLDMTypes); 72 73 /** @brief Check if the terminus supports the PLDM type message 74 * 75 * @param[in] type - PLDM Type 76 * @return support state - True if support, otherwise False 77 */ 78 bool doesSupportType(uint8_t type); 79 80 /** @brief Check if the terminus supports the PLDM command message 81 * 82 * @param[in] type - PLDM Type 83 * @param[in] command - PLDM command 84 * @return support state - True if support, otherwise False 85 */ 86 bool doesSupportCommand(uint8_t type, uint8_t command); 87 88 /** @brief Set the supported PLDM commands for terminus 89 * 90 * @param[in] cmds - bit mask of the supported PLDM commands 91 * @return success state - True if success, otherwise False 92 */ setSupportedCommands(const std::vector<uint8_t> & cmds)93 bool setSupportedCommands(const std::vector<uint8_t>& cmds) 94 { 95 const size_t expectedSize = 96 PLDM_MAX_TYPES * (PLDM_MAX_CMDS_PER_TYPE / 8); 97 if (cmds.empty() || cmds.size() != expectedSize) 98 { 99 lg2::error( 100 "setSupportedCommands received invalid bit mask size. Expected: {EXPECTED}, Received: {RECEIVED}", 101 "EXPECTED", expectedSize, "RECEIVED", cmds.size()); 102 return false; 103 } 104 105 /* Assign Vector supportedCmds by Vector cmds */ 106 supportedCmds.resize(cmds.size()); 107 std::copy(cmds.begin(), cmds.begin() + cmds.size(), 108 supportedCmds.begin()); 109 110 return true; 111 } 112 113 /** @brief Set the PLDM supported type version for terminus 114 * 115 * @param[in] type - PLDM supported types 116 * @param[in] version - PLDM supported type version 117 * @return success state - True if success, otherwise False 118 */ setSupportedTypeVersions(const uint8_t type,const ver32_t version)119 inline bool setSupportedTypeVersions(const uint8_t type, 120 const ver32_t version) 121 { 122 if (type > PLDM_MAX_TYPES || type >= supportedTypeVersions.size()) 123 { 124 return false; 125 } 126 supportedTypeVersions[type] = version; 127 128 return true; 129 } 130 131 /** @brief Parse the PDRs stored in the member variable, pdrs. 132 */ 133 void parseTerminusPDRs(); 134 135 /** @brief The getter to return terminus's TID */ getTid()136 pldm_tid_t getTid() 137 { 138 return tid; 139 } 140 141 /** @brief The getter to get terminus's mctp medium */ getTerminusName()142 std::optional<std::string_view> getTerminusName() 143 { 144 if (terminusName.empty()) 145 { 146 return std::nullopt; 147 } 148 return terminusName; 149 } 150 151 /** @brief Parse record data from FRU table 152 * 153 * @param[in] fruData - pointer to FRU record table 154 * @param[in] fruLen - FRU table length 155 */ 156 void updateInventoryWithFru(const uint8_t* fruData, const size_t fruLen); 157 158 /** @brief A list of PDRs fetched from Terminus */ 159 std::vector<std::vector<uint8_t>> pdrs{}; 160 161 /** @brief A flag to indicate if terminus has been initialized */ 162 bool initialized = false; 163 164 /** @brief maximum message buffer size the terminus can send and receive */ 165 uint16_t maxBufferSize; 166 167 /** @brief This value indicates the event messaging styles supported by the 168 * terminus 169 */ 170 bitfield8_t synchronyConfigurationSupported; 171 172 /** @brief A list of numericSensors */ 173 std::vector<std::shared_ptr<NumericSensor>> numericSensors{}; 174 175 /** @brief The flag indicates that the terminus FIFO contains a large 176 * message that will require a multipart transfer via the 177 * PollForPlatformEvent command 178 */ 179 bool pollEvent; 180 181 /** @brief The sensor id is used in pollForPlatformMessage command */ 182 uint16_t pollEventId; 183 184 /** @brief The dataTransferHandle from `pldmMessagePollEvent` event and will 185 * be used as `dataTransferHandle` for pollForPlatformMessage 186 * command. 187 */ 188 uint32_t pollDataTransferHandle; 189 190 /** @brief Get Sensor Auxiliary Names by sensorID 191 * 192 * @param[in] id - sensor ID 193 * @return sensor auxiliary names 194 */ 195 std::shared_ptr<SensorAuxiliaryNames> getSensorAuxiliaryNames(SensorId id); 196 197 /** @brief Get Numeric Sensor Object by sensorID 198 * 199 * @param[in] id - sensor ID 200 * 201 * @return sensor object 202 */ 203 std::shared_ptr<NumericSensor> getSensorObject(SensorId id); 204 205 private: 206 /** @brief Find the Terminus Name from the Entity Auxiliary name list 207 * The Entity Auxiliary name list is entityAuxiliaryNamesTbl. 208 * @return terminus name in string option 209 */ 210 std::optional<std::string_view> findTerminusName(); 211 212 /** @brief Construct the NumericSensor sensor class for the PLDM sensor. 213 * The NumericSensor class will handle create D-Bus object path, 214 * provide the APIs to update sensor value, threshold... 215 * 216 * @param[in] pdr - the numeric sensor PDR info 217 */ 218 void addNumericSensor( 219 const std::shared_ptr<pldm_numeric_sensor_value_pdr> pdr); 220 221 /** @brief Parse the numeric sensor PDRs 222 * 223 * @param[in] pdrData - the response PDRs from GetPDR command 224 * @return pointer to numeric sensor info struct 225 */ 226 std::shared_ptr<pldm_numeric_sensor_value_pdr> 227 parseNumericSensorPDR(const std::vector<uint8_t>& pdrData); 228 229 /** @brief Parse the sensor Auxiliary name PDRs 230 * 231 * @param[in] pdrData - the response PDRs from GetPDR command 232 * @return pointer to sensor Auxiliary name info struct 233 */ 234 std::shared_ptr<SensorAuxiliaryNames> 235 parseSensorAuxiliaryNamesPDR(const std::vector<uint8_t>& pdrData); 236 237 /** @brief Parse the Entity Auxiliary name PDRs 238 * 239 * @param[in] pdrData - the response PDRs from GetPDR command 240 * @return pointer to Entity Auxiliary name info struct 241 */ 242 std::shared_ptr<EntityAuxiliaryNames> 243 parseEntityAuxiliaryNamesPDR(const std::vector<uint8_t>& pdrData); 244 245 /** @brief Construct the NumericSensor sensor class for the compact numeric 246 * PLDM sensor. 247 * 248 * @param[in] pdr - the compact numeric sensor PDR info 249 */ 250 void addCompactNumericSensor( 251 const std::shared_ptr<pldm_compact_numeric_sensor_pdr> pdr); 252 253 /** @brief Parse the compact numeric sensor PDRs 254 * 255 * @param[in] pdrData - the response PDRs from GetPDR command 256 * @return pointer to compact numeric sensor info struct 257 */ 258 std::shared_ptr<pldm_compact_numeric_sensor_pdr> 259 parseCompactNumericSensorPDR(const std::vector<uint8_t>& pdrData); 260 261 /** @brief Parse the sensor Auxiliary name from compact numeric sensor PDRs 262 * 263 * @param[in] pdrData - the response PDRs from GetPDR command 264 * @return pointer to sensor Auxiliary name info struct 265 */ 266 std::shared_ptr<SensorAuxiliaryNames> 267 parseCompactNumericSensorNames(const std::vector<uint8_t>& pdrData); 268 269 /** @brief Create the terminus inventory path to 270 * /xyz/openbmc_project/inventory/Item/Board/. 271 * 272 * @param[in] tName - the terminus name 273 * @return true/false: True if there is no error in creating inventory path 274 * 275 */ 276 bool createInventoryPath(std::string tName); 277 278 /* @brief The terminus's TID */ 279 pldm_tid_t tid; 280 281 /* @brief The supported PLDM command types of the terminus */ 282 std::bitset<64> supportedTypes; 283 284 /** @brief Store supported PLDM commands of a terminus 285 * Maximum number of PLDM Type is PLDM_MAX_TYPES 286 * Maximum number of PLDM command for each type is 287 * PLDM_MAX_CMDS_PER_TYPE. 288 * Each uint8_t can store the supported state of 8 PLDM commands. 289 * Size of supportedCmds will be 290 * PLDM_MAX_TYPES * (PLDM_MAX_CMDS_PER_TYPE / 8). 291 */ 292 std::vector<uint8_t> supportedCmds; 293 294 /* @brief The PLDM supported type version */ 295 std::map<uint8_t, ver32_t> supportedTypeVersions; 296 297 /* @brief Sensor Auxiliary Name list */ 298 std::vector<std::shared_ptr<SensorAuxiliaryNames>> 299 sensorAuxiliaryNamesTbl{}; 300 301 /* @brief Entity Auxiliary Name list */ 302 std::vector<std::shared_ptr<EntityAuxiliaryNames>> 303 entityAuxiliaryNamesTbl{}; 304 305 /** @brief Terminus name */ 306 EntityName terminusName{}; 307 /* @brief The pointer of inventory D-Bus interface for the terminus */ 308 std::unique_ptr<pldm::dbus_api::PldmEntityReq> inventoryItemBoardInft = 309 nullptr; 310 311 /* @brief Inventory D-Bus object path of the terminus */ 312 std::string inventoryPath; 313 }; 314 } // namespace platform_mc 315 } // namespace pldm 316