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