1 #pragma once 2 3 #include "const.hpp" 4 #include "types.hpp" 5 6 #include <nlohmann/json.hpp> 7 8 #include <cstddef> 9 #include <fstream> 10 #include <tuple> 11 12 namespace openpower 13 { 14 namespace vpd 15 { 16 namespace manager 17 { 18 namespace editor 19 { 20 21 /** @class EditorImpl */ 22 class EditorImpl 23 { 24 public: 25 EditorImpl() = delete; 26 EditorImpl(const EditorImpl&) = delete; 27 EditorImpl& operator=(const EditorImpl&) = delete; 28 EditorImpl(EditorImpl&&) = delete; 29 EditorImpl& operator=(EditorImpl&&) = delete; ~EditorImpl()30 ~EditorImpl() {} 31 32 /** @brief Construct EditorImpl class 33 * 34 * @param[in] record - Record Name 35 * @param[in] kwd - Keyword 36 * @param[in] vpd - Vpd Vector 37 */ EditorImpl(const std::string & record,const std::string & kwd,Binary && vpd)38 EditorImpl(const std::string& record, const std::string& kwd, 39 Binary&& vpd) : 40 startOffset(0), 41 thisRecord(record, kwd), vpdFile(std::move(vpd)) 42 {} 43 44 /** @brief Construct EditorImpl class 45 * 46 * @param[in] path - Path to the vpd file 47 * @param[in] json - Parsed inventory json 48 * @param[in] record - Record name 49 * @param[in] kwd - Keyword 50 * @param[in] inventoryPath - Inventory path of the vpd 51 */ EditorImpl(const inventory::Path & path,const nlohmann::json & json,const std::string & record,const std::string & kwd,const sdbusplus::message::object_path & inventoryPath)52 EditorImpl(const inventory::Path& path, const nlohmann::json& json, 53 const std::string& record, const std::string& kwd, 54 const sdbusplus::message::object_path& inventoryPath) : 55 vpdFilePath(path), 56 objPath(inventoryPath), startOffset(0), jsonFile(json), 57 thisRecord(record, kwd) 58 {} 59 60 /** @brief Construct EditorImpl class 61 * 62 * @param[in] path - EEPROM path 63 * @param[in] json - Parsed inventory json object 64 * @param[in] record - Record name 65 * @param[in] kwd - Keyword name 66 */ EditorImpl(const inventory::Path & path,const nlohmann::json & json,const std::string & record,const std::string & kwd)67 EditorImpl(const inventory::Path& path, const nlohmann::json& json, 68 const std::string& record, const std::string& kwd) : 69 vpdFilePath(path), 70 jsonFile(json), thisRecord(record, kwd) 71 {} 72 73 /** 74 * @brief Update data for keyword 75 * The method looks for the record name to update in VTOC and then 76 * looks for the keyword name in that record. when found it updates the data 77 * of keyword with the given data. It does not block keyword data update in 78 * case the length of new data is greater than or less than the current data 79 * length. If the new data length is more than the length allotted to that 80 * keyword the new data will be truncated to update only the allotted 81 * length. Similarly if the new data length is less then only that much data 82 * will be updated for the keyword and remaining bits will be left 83 * unchanged. 84 * 85 * Following is the algorithm used to update keyword: 86 * 1) Look for the record name in the given VPD file 87 * 2) Look for the keyword name for which data needs to be updated 88 * which is the table of contents record. 89 * 3) update the data for that keyword with the new data 90 * 91 * @param[in] kwdData - data to update 92 * @param[in] offset - offset at which the VPD starts 93 * @param[in] updCache - Flag which tells whether to update Cache or not. 94 */ 95 void updateKeyword(const Binary& kwdData, uint32_t offset, 96 const bool& updCache); 97 98 /** @brief Expands location code on DBUS 99 * @param[in] locationCodeType - "fcs" or "mts" 100 */ 101 void expandLocationCode(const std::string& locationCodeType); 102 103 private: 104 /** @brief read VTOC record from the vpd file 105 */ 106 void readVTOC(); 107 108 /** @brief validate ecc data for the VTOC record 109 * @param[in] itrToRecData -iterator to the record data 110 * @param[in] itrToECCData - iterator to the ECC data 111 * @param[in] recLength - Length of the record 112 * @param[in] eccLength - Length of the record's ECC 113 */ 114 void checkECC(Binary::const_iterator& itrToRecData, 115 Binary::const_iterator& itrToECCData, 116 openpower::vpd::constants::RecordLength recLength, 117 openpower::vpd::constants::ECCLength eccLength); 118 119 /** @brief reads value at the given offset 120 * @param[in] offset - offset value 121 * @return value at that offset in bigendian 122 */ 123 auto getValue(openpower::vpd::constants::offsets::Offsets offset); 124 125 /** @brief Checks if required record name exist in the VPD file 126 * @param[in] iterator - pointing to start of PT kwd 127 * @param[in] ptLength - length of the PT kwd 128 */ 129 void checkPTForRecord(Binary::const_iterator& iterator, Byte ptLength); 130 131 /** @brief Checks for required keyword in the record */ 132 void checkRecordForKwd(); 133 134 /** @brief update data for given keyword 135 * @param[in] kwdData- data to be updated 136 */ 137 void updateData(const Binary& kwdData); 138 139 /** @brief update record ECC */ 140 void updateRecordECC(); 141 142 /** @brief method to update cache once the data for keyword has been updated 143 */ 144 void updateCache(); 145 146 /** @brief method to process and update CI in case required 147 * @param[in] - objectPath - path of the object to introspect 148 */ 149 void processAndUpdateCI(const std::string& objectPath); 150 151 /** @brief method to process and update extra interface 152 * @param[in] Inventory - single inventory json subpart 153 * @param[in] objPath - path of the object to introspect 154 */ 155 void processAndUpdateEI(const nlohmann::json& Inventory, 156 const inventory::Path& objPath); 157 158 /** @brief method to make busctl call 159 * 160 * @param[in] object - bus object path 161 * @param[in] interface - bus interface 162 * @param[in] property - property to update on BUS 163 * @param[in] data - data to be updated on Bus 164 * 165 */ 166 template <typename T> 167 void makeDbusCall(const std::string& object, const std::string& interface, 168 const std::string& property, const std::variant<T>& data); 169 170 /** @brief Method to check the record's Data using ECC */ 171 void checkRecordData(); 172 173 // path to the VPD file to edit 174 inventory::Path vpdFilePath; 175 176 // inventory path of the vpd fru to update keyword 177 inventory::Path objPath{}; 178 179 // stream to perform operation on file 180 std::fstream vpdFileStream; 181 182 // stream to operate on VPD data 183 std::fstream vpdDataFileStream; 184 185 // offset to get vpd data from EEPROM 186 uint32_t startOffset; 187 188 // file to store parsed json 189 const nlohmann::json jsonFile; 190 191 // structure to hold info about record to edit 192 struct RecInfo 193 { 194 Binary kwdUpdatedData; // need access to it in case encoding is needed 195 const std::string recName; 196 const std::string recKWd; 197 openpower::vpd::constants::RecordOffset recOffset; 198 openpower::vpd::constants::ECCOffset recECCoffset; 199 std::size_t recECCLength; 200 std::size_t kwdDataLength; 201 openpower::vpd::constants::RecordSize recSize; 202 openpower::vpd::constants::DataOffset kwDataOffset; 203 // constructor RecInfoopenpower::vpd::manager::editor::EditorImpl::RecInfo204 RecInfo(const std::string& rec, const std::string& kwd) : 205 recName(rec), recKWd(kwd), recOffset(0), recECCoffset(0), 206 recECCLength(0), kwdDataLength(0), recSize(0), kwDataOffset(0) 207 {} 208 } thisRecord; 209 210 Binary vpdFile; 211 212 // If requested Interface is common Interface 213 bool isCI; 214 }; // class EditorImpl 215 216 } // namespace editor 217 } // namespace manager 218 } // namespace vpd 219 } // namespace openpower 220