1 #pragma once 2 3 #include "backup_restore.hpp" 4 #include "constants.hpp" 5 #include "gpio_monitor.hpp" 6 #include "types.hpp" 7 #include "worker.hpp" 8 9 #include <sdbusplus/asio/object_server.hpp> 10 11 namespace vpd 12 { 13 /** 14 * @brief Class to manage VPD processing. 15 * 16 * The class is responsible to implement methods to manage VPD on the system. 17 * It also implements methods to be exposed over D-Bus required to access/edit 18 * VPD data. 19 */ 20 class Manager 21 { 22 public: 23 /** 24 * List of deleted methods. 25 */ 26 Manager(const Manager&) = delete; 27 Manager& operator=(const Manager&) = delete; 28 Manager(Manager&&) = delete; 29 30 /** 31 * @brief Constructor. 32 * 33 * @param[in] ioCon - IO context. 34 * @param[in] iFace - interface to implement. 35 * @param[in] connection - Dbus Connection. 36 */ 37 Manager(const std::shared_ptr<boost::asio::io_context>& ioCon, 38 const std::shared_ptr<sdbusplus::asio::dbus_interface>& iFace, 39 const std::shared_ptr<sdbusplus::asio::connection>& asioConnection); 40 41 /** 42 * @brief Destructor. 43 */ 44 ~Manager() = default; 45 46 /** 47 * @brief Update keyword value. 48 * 49 * This API is used to update keyword value on the given input path and its 50 * redundant path(s) if any taken from system config JSON. 51 * 52 * To update IPZ type VPD, input parameter for writing should be in the form 53 * of (Record, Keyword, Value). Eg: ("VINI", "SN", {0x01, 0x02, 0x03}). 54 * 55 * To update Keyword type VPD, input parameter for writing should be in the 56 * form of (Keyword, Value). Eg: ("PE", {0x01, 0x02, 0x03}). 57 * 58 * @param[in] i_vpdPath - Path (inventory object path/FRU EEPROM path). 59 * @param[in] i_paramsToWriteData - Input details. 60 * 61 * @return On success returns number of bytes written, on failure returns 62 * -1. 63 */ 64 int updateKeyword(const types::Path i_vpdPath, 65 const types::WriteVpdParams i_paramsToWriteData); 66 67 /** 68 * @brief Update keyword value on hardware. 69 * 70 * This API is used to update keyword value on hardware. Updates only on the 71 * given input hardware path, does not look for corresponding redundant or 72 * primary path against the given path. To update corresponding paths, make 73 * separate call with respective path. 74 * 75 * To update IPZ type VPD, input parameter for writing should be in the form 76 * of (Record, Keyword, Value). Eg: ("VINI", "SN", {0x01, 0x02, 0x03}). 77 * 78 * To update Keyword type VPD, input parameter for writing should be in the 79 * form of (Keyword, Value). Eg: ("PE", {0x01, 0x02, 0x03}). 80 * 81 * @param[in] i_fruPath - EEPROM path of the FRU. 82 * @param[in] i_paramsToWriteData - Input details. 83 * 84 * @return On success returns number of bytes written, on failure returns 85 * -1. 86 */ 87 int updateKeywordOnHardware( 88 const types::Path i_fruPath, 89 const types::WriteVpdParams i_paramsToWriteData) noexcept; 90 91 /** 92 * @brief Read keyword value. 93 * 94 * API can be used to read VPD keyword from the given input path. 95 * 96 * To read keyword of type IPZ, input parameter for reading should be in the 97 * form of (Record, Keyword). Eg: ("VINI", "SN"). 98 * 99 * To read keyword from keyword type VPD, just keyword name has to be 100 * supplied in the input parameter. Eg: ("SN"). 101 * 102 * @param[in] i_fruPath - EEPROM path. 103 * @param[in] i_paramsToReadData - Input details. 104 * 105 * @throw 106 * sdbusplus::xyz::openbmc_project::Common::Device::Error::ReadFailure. 107 * 108 * @return On success returns the read value in variant of array of bytes. 109 * On failure throws exception. 110 */ 111 types::DbusVariantType readKeyword( 112 const types::Path i_fruPath, 113 const types::ReadVpdParams i_paramsToReadData); 114 115 /** 116 * @brief Collect single FRU VPD 117 * API can be used to perform VPD collection for the given FRU, only if the 118 * current state of the system matches with the state at which the FRU is 119 * allowed for VPD recollection. 120 * 121 * @param[in] i_dbusObjPath - D-bus object path 122 */ 123 void collectSingleFruVpd( 124 const sdbusplus::message::object_path& i_dbusObjPath); 125 126 /** 127 * @brief Delete single FRU VPD 128 * API can be used to perform VPD deletion for the given FRU. 129 * 130 * @param[in] i_dbusObjPath - D-bus object path 131 */ 132 void deleteSingleFruVpd( 133 const sdbusplus::message::object_path& i_dbusObjPath); 134 135 /** 136 * @brief Get expanded location code. 137 * 138 * API to get expanded location code from the unexpanded location code. 139 * 140 * @param[in] i_unexpandedLocationCode - Unexpanded location code. 141 * @param[in] i_nodeNumber - Denotes the node in case of a multi-node 142 * configuration, defaulted to zero incase of single node system. 143 * 144 * @throw xyz.openbmc_project.Common.Error.InvalidArgument for 145 * invalid argument. 146 * 147 * @return Location code of the FRU. 148 */ 149 std::string getExpandedLocationCode( 150 const std::string& i_unexpandedLocationCode, 151 [[maybe_unused]] const uint16_t i_nodeNumber = 0); 152 153 /** 154 * @brief Get D-Bus object path of FRUs from expanded location code. 155 * 156 * An API to get list of FRU D-Bus object paths for a given expanded 157 * location code. 158 * 159 * @param[in] i_expandedLocationCode - Expanded location code. 160 * 161 * @throw xyz.openbmc_project.Common.Error.InvalidArgument for 162 * invalid argument. 163 * 164 * @return List of FRUs D-Bus object paths for the given location code. 165 */ 166 types::ListOfPaths getFrusByExpandedLocationCode( 167 const std::string& i_expandedLocationCode); 168 169 /** 170 * @brief Get D-Bus object path of FRUs from unexpanded location code. 171 * 172 * An API to get list of FRU D-Bus object paths for a given unexpanded 173 * location code. 174 * 175 * @param[in] i_unexpandedLocationCode - Unexpanded location code. 176 * @param[in] i_nodeNumber - Denotes the node in case of a multi-node 177 * configuration, defaulted to zero incase of single node system. 178 * 179 * @throw xyz.openbmc_project.Common.Error.InvalidArgument for 180 * invalid argument. 181 * 182 * @return List of FRUs D-Bus object paths for the given location code. 183 */ 184 types::ListOfPaths getFrusByUnexpandedLocationCode( 185 const std::string& i_unexpandedLocationCode, 186 [[maybe_unused]] const uint16_t i_nodeNumber = 0); 187 188 /** 189 * @brief Get Hardware path 190 * API can be used to get EEPROM path for the given inventory path. 191 * 192 * @param[in] i_dbusObjPath - D-bus object path 193 * 194 * @return Corresponding EEPROM path. 195 */ 196 std::string getHwPath(const sdbusplus::message::object_path& i_dbusObjPath); 197 198 /** 199 * @brief Perform VPD recollection 200 * This api will trigger parser to perform VPD recollection for FRUs that 201 * can be replaced at standby. 202 */ 203 void performVpdRecollection(); 204 205 /** 206 * @brief Get unexpanded location code. 207 * 208 * An API to get unexpanded location code and node number from expanded 209 * location code. 210 * 211 * @param[in] i_expandedLocationCode - Expanded location code. 212 * 213 * @throw xyz.openbmc_project.Common.Error.InvalidArgument for 214 * invalid argument. 215 * 216 * @return Location code in unexpanded format and its node number. 217 */ 218 std::tuple<std::string, uint16_t> getUnexpandedLocationCode( 219 const std::string& i_expandedLocationCode); 220 221 private: 222 #ifdef IBM_SYSTEM 223 /** 224 * @brief API to set timer to detect system VPD over D-Bus. 225 * 226 * System VPD is required before bus name for VPD-Manager is claimed. Once 227 * system VPD is published, VPD for other FRUs should be collected. This API 228 * detects id system VPD is already published on D-Bus and based on that 229 * triggers VPD collection for rest of the FRUs. 230 * 231 * Note: Throws exception in case of any failure. Needs to be handled by the 232 * caller. 233 */ 234 void SetTimerToDetectSVPDOnDbus(); 235 236 /** 237 * @brief Set timer to detect and set VPD collection status for the system. 238 * 239 * Collection of FRU VPD is triggered in a separate thread. Resulting in 240 * multiple threads at a given time. The API creates a timer which on 241 * regular interval will check if all the threads were collected back and 242 * sets the status of the VPD collection for the system accordingly. 243 * 244 * @throw std::runtime_error 245 */ 246 void SetTimerToDetectVpdCollectionStatus(); 247 248 /** 249 * @brief API to register callback for "AssetTag" property change. 250 */ 251 void registerAssetTagChangeCallback(); 252 253 /** 254 * @brief Callback API to be triggered on "AssetTag" property change. 255 * 256 * @param[in] i_msg - The callback message. 257 */ 258 void processAssetTagChangeCallback(sdbusplus::message_t& i_msg); 259 260 /** 261 * @brief API to process VPD collection thread failed EEPROMs. 262 */ 263 void processFailedEeproms(); 264 265 /** 266 * @brief API to check and update PowerVS VPD. 267 * 268 * The API will read the existing data from the DBus and if found 269 * different than what has been read from JSON, it will update the VPD with 270 * JSON data on hardware and DBus both. 271 * 272 * @param[in] i_powerVsJsonObj - PowerVS JSON object. 273 * @param[out] o_failedPathList - List of path failed to update. 274 */ 275 void checkAndUpdatePowerVsVpd(const nlohmann::json& i_powerVsJsonObj, 276 std::vector<std::string>& o_failedPathList); 277 278 /** 279 * @brief API to handle configuration w.r.t. PowerVS systems. 280 * 281 * Some FRUs VPD is specific to powerVS system. The API detects the 282 * powerVS configuration and updates the VPD accordingly. 283 */ 284 void ConfigurePowerVsSystem(); 285 #endif 286 287 /** 288 * @brief An api to check validity of unexpanded location code. 289 * 290 * @param[in] i_locationCode - Unexpanded location code. 291 * 292 * @return True/False based on validity check. 293 */ 294 bool isValidUnexpandedLocationCode(const std::string& i_locationCode); 295 296 /** 297 * @brief API to register callback for Host state change. 298 */ 299 void registerHostStateChangeCallback(); 300 301 /** 302 * @brief API to process host state change callback. 303 * 304 * @param[in] i_msg - Callback message. 305 */ 306 void hostStateChangeCallBack(sdbusplus::message_t& i_msg); 307 308 // Shared pointer to asio context object. 309 const std::shared_ptr<boost::asio::io_context>& m_ioContext; 310 311 // Shared pointer to Dbus interface class. 312 const std::shared_ptr<sdbusplus::asio::dbus_interface>& m_interface; 313 314 // Shared pointer to bus connection. 315 const std::shared_ptr<sdbusplus::asio::connection>& m_asioConnection; 316 317 // Shared pointer to worker class 318 std::shared_ptr<Worker> m_worker; 319 320 // Shared pointer to GpioMonitor class 321 std::shared_ptr<GpioMonitor> m_gpioMonitor; 322 323 // Variable to hold current collection status 324 std::string m_vpdCollectionStatus = "NotStarted"; 325 326 // Shared pointer to backup and restore class 327 std::shared_ptr<BackupAndRestore> m_backupAndRestoreObj; 328 }; 329 330 } // namespace vpd 331