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