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