| SunnySrivastava1984 | a739259 | 2020-03-09 10:19:33 -0500 | [diff] [blame] | 1 | #include "config.h" | 
|  | 2 |  | 
| SunnySrivastava1984 | f6d541e | 2020-02-04 12:50:40 -0600 | [diff] [blame] | 3 | #include "editor_impl.hpp" | 
|  | 4 |  | 
| Alpana Kumari | 414d5ae | 2021-03-04 21:06:35 +0000 | [diff] [blame] | 5 | #include "common_utility.hpp" | 
| Sunny Srivastava | 6c71c9d | 2021-04-15 04:43:54 -0500 | [diff] [blame] | 6 | #include "ibm_vpd_utils.hpp" | 
| SunnySrivastava1984 | e12b181 | 2020-05-26 02:23:11 -0500 | [diff] [blame] | 7 | #include "ipz_parser.hpp" | 
|  | 8 | #include "parser_factory.hpp" | 
| Priyanga Ramasamy | c99a0b0 | 2022-06-08 14:53:39 -0500 | [diff] [blame] | 9 | #include "vpd_exceptions.hpp" | 
| SunnySrivastava1984 | f6d541e | 2020-02-04 12:50:40 -0600 | [diff] [blame] | 10 |  | 
| Sunny Srivastava | f31a91b | 2022-06-09 08:11:29 -0500 | [diff] [blame] | 11 | #include <phosphor-logging/elog-errors.hpp> | 
|  | 12 | #include <xyz/openbmc_project/Common/error.hpp> | 
|  | 13 |  | 
| SunnySrivastava1984 | f6d541e | 2020-02-04 12:50:40 -0600 | [diff] [blame] | 14 | #include "vpdecc/vpdecc.h" | 
|  | 15 |  | 
| SunnySrivastava1984 | e12b181 | 2020-05-26 02:23:11 -0500 | [diff] [blame] | 16 | using namespace openpower::vpd::parser::interface; | 
|  | 17 | using namespace openpower::vpd::constants; | 
|  | 18 | using namespace openpower::vpd::parser::factory; | 
|  | 19 | using namespace openpower::vpd::ipz::parser; | 
|  | 20 |  | 
| SunnySrivastava1984 | f6d541e | 2020-02-04 12:50:40 -0600 | [diff] [blame] | 21 | namespace openpower | 
|  | 22 | { | 
|  | 23 | namespace vpd | 
|  | 24 | { | 
|  | 25 | namespace manager | 
|  | 26 | { | 
|  | 27 | namespace editor | 
|  | 28 | { | 
| SunnySrivastava1984 | f6d541e | 2020-02-04 12:50:40 -0600 | [diff] [blame] | 29 |  | 
|  | 30 | void EditorImpl::checkPTForRecord(Binary::const_iterator& iterator, | 
|  | 31 | Byte ptLength) | 
|  | 32 | { | 
|  | 33 | // auto iterator = ptRecord.cbegin(); | 
|  | 34 | auto end = std::next(iterator, ptLength + 1); | 
|  | 35 |  | 
|  | 36 | // Look at each entry in the PT keyword for the record name | 
|  | 37 | while (iterator < end) | 
|  | 38 | { | 
|  | 39 | auto stop = std::next(iterator, lengths::RECORD_NAME); | 
|  | 40 | std::string record(iterator, stop); | 
|  | 41 |  | 
|  | 42 | if (record == thisRecord.recName) | 
|  | 43 | { | 
|  | 44 | // Skip record name and record type | 
|  | 45 | std::advance(iterator, lengths::RECORD_NAME + sizeof(RecordType)); | 
|  | 46 |  | 
|  | 47 | // Get record offset | 
|  | 48 | thisRecord.recOffset = readUInt16LE(iterator); | 
|  | 49 |  | 
|  | 50 | // pass the record offset length to read record length | 
|  | 51 | std::advance(iterator, lengths::RECORD_OFFSET); | 
|  | 52 | thisRecord.recSize = readUInt16LE(iterator); | 
|  | 53 |  | 
|  | 54 | std::advance(iterator, lengths::RECORD_LENGTH); | 
|  | 55 | thisRecord.recECCoffset = readUInt16LE(iterator); | 
|  | 56 |  | 
|  | 57 | ECCLength len; | 
|  | 58 | std::advance(iterator, lengths::RECORD_ECC_OFFSET); | 
|  | 59 | len = readUInt16LE(iterator); | 
|  | 60 | thisRecord.recECCLength = len; | 
|  | 61 |  | 
|  | 62 | // once we find the record we don't need to look further | 
|  | 63 | return; | 
|  | 64 | } | 
|  | 65 | else | 
|  | 66 | { | 
|  | 67 | // Jump the record | 
|  | 68 | std::advance(iterator, lengths::RECORD_NAME + sizeof(RecordType) + | 
|  | 69 | sizeof(RecordOffset) + | 
|  | 70 | sizeof(RecordLength) + | 
|  | 71 | sizeof(ECCOffset) + sizeof(ECCLength)); | 
|  | 72 | } | 
|  | 73 | } | 
| SunnySrivastava1984 | f6d541e | 2020-02-04 12:50:40 -0600 | [diff] [blame] | 74 | // imples the record was not found | 
|  | 75 | throw std::runtime_error("Record not found"); | 
|  | 76 | } | 
|  | 77 |  | 
| SunnySrivastava1984 | 6d8314d | 2020-05-15 09:34:58 -0500 | [diff] [blame] | 78 | void EditorImpl::updateData(const Binary& kwdData) | 
| SunnySrivastava1984 | f6d541e | 2020-02-04 12:50:40 -0600 | [diff] [blame] | 79 | { | 
|  | 80 | std::size_t lengthToUpdate = kwdData.size() <= thisRecord.kwdDataLength | 
|  | 81 | ? kwdData.size() | 
|  | 82 | : thisRecord.kwdDataLength; | 
|  | 83 |  | 
|  | 84 | auto iteratorToNewdata = kwdData.cbegin(); | 
|  | 85 | auto end = iteratorToNewdata; | 
|  | 86 | std::advance(end, lengthToUpdate); | 
|  | 87 |  | 
| SunnySrivastava1984 | 6d8314d | 2020-05-15 09:34:58 -0500 | [diff] [blame] | 88 | // update data in file buffer as it will be needed to update ECC | 
|  | 89 | // avoiding extra stream operation here | 
|  | 90 | auto iteratorToKWdData = vpdFile.begin(); | 
|  | 91 | std::advance(iteratorToKWdData, thisRecord.kwDataOffset); | 
|  | 92 | std::copy(iteratorToNewdata, end, iteratorToKWdData); | 
|  | 93 |  | 
| SunnySrivastava1984 | a0d460e | 2020-06-03 07:49:26 -0500 | [diff] [blame] | 94 | #ifdef ManagerTest | 
|  | 95 | auto startItr = vpdFile.begin(); | 
|  | 96 | std::advance(iteratorToKWdData, thisRecord.kwDataOffset); | 
|  | 97 | auto endItr = startItr; | 
|  | 98 | std::advance(endItr, thisRecord.kwdDataLength); | 
|  | 99 |  | 
|  | 100 | Binary updatedData(startItr, endItr); | 
|  | 101 | if (updatedData == kwdData) | 
|  | 102 | { | 
|  | 103 | throw std::runtime_error("Data updated successfully"); | 
|  | 104 | } | 
|  | 105 | #else | 
|  | 106 |  | 
| SunnySrivastava1984 | 6d8314d | 2020-05-15 09:34:58 -0500 | [diff] [blame] | 107 | // update data in EEPROM as well. As we will not write complete file back | 
| SunnySrivastava1984 | e12b181 | 2020-05-26 02:23:11 -0500 | [diff] [blame] | 108 | vpdFileStream.seekp(startOffset + thisRecord.kwDataOffset, std::ios::beg); | 
| Alpana Kumari | 920408d | 2020-05-14 00:07:03 -0500 | [diff] [blame] | 109 |  | 
| SunnySrivastava1984 | 6d8314d | 2020-05-15 09:34:58 -0500 | [diff] [blame] | 110 | iteratorToNewdata = kwdData.cbegin(); | 
| SunnySrivastava1984 | f6d541e | 2020-02-04 12:50:40 -0600 | [diff] [blame] | 111 | std::copy(iteratorToNewdata, end, | 
|  | 112 | std::ostreambuf_iterator<char>(vpdFileStream)); | 
| SunnySrivastava1984 | 6d8314d | 2020-05-15 09:34:58 -0500 | [diff] [blame] | 113 |  | 
|  | 114 | // get a hold to new data in case encoding is needed | 
|  | 115 | thisRecord.kwdUpdatedData.resize(thisRecord.kwdDataLength); | 
|  | 116 | auto itrToKWdData = vpdFile.cbegin(); | 
|  | 117 | std::advance(itrToKWdData, thisRecord.kwDataOffset); | 
|  | 118 | auto kwdDataEnd = itrToKWdData; | 
|  | 119 | std::advance(kwdDataEnd, thisRecord.kwdDataLength); | 
|  | 120 | std::copy(itrToKWdData, kwdDataEnd, thisRecord.kwdUpdatedData.begin()); | 
| SunnySrivastava1984 | a0d460e | 2020-06-03 07:49:26 -0500 | [diff] [blame] | 121 | #endif | 
| SunnySrivastava1984 | f6d541e | 2020-02-04 12:50:40 -0600 | [diff] [blame] | 122 | } | 
|  | 123 |  | 
|  | 124 | void EditorImpl::checkRecordForKwd() | 
|  | 125 | { | 
|  | 126 | RecordOffset recOffset = thisRecord.recOffset; | 
|  | 127 |  | 
| SunnySrivastava1984 | 6d8314d | 2020-05-15 09:34:58 -0500 | [diff] [blame] | 128 | // Amount to skip for record ID, size, and the RT keyword | 
|  | 129 | constexpr auto skipBeg = sizeof(RecordId) + sizeof(RecordSize) + | 
|  | 130 | lengths::KW_NAME + sizeof(KwSize); | 
| SunnySrivastava1984 | f6d541e | 2020-02-04 12:50:40 -0600 | [diff] [blame] | 131 |  | 
| SunnySrivastava1984 | 6d8314d | 2020-05-15 09:34:58 -0500 | [diff] [blame] | 132 | auto iterator = vpdFile.cbegin(); | 
|  | 133 | std::advance(iterator, recOffset + skipBeg + lengths::RECORD_NAME); | 
| SunnySrivastava1984 | f6d541e | 2020-02-04 12:50:40 -0600 | [diff] [blame] | 134 |  | 
| SunnySrivastava1984 | 6d8314d | 2020-05-15 09:34:58 -0500 | [diff] [blame] | 135 | auto end = iterator; | 
|  | 136 | std::advance(end, thisRecord.recSize); | 
| SunnySrivastava1984 | f6d541e | 2020-02-04 12:50:40 -0600 | [diff] [blame] | 137 | std::size_t dataLength = 0; | 
| SunnySrivastava1984 | 6d8314d | 2020-05-15 09:34:58 -0500 | [diff] [blame] | 138 |  | 
| SunnySrivastava1984 | f6d541e | 2020-02-04 12:50:40 -0600 | [diff] [blame] | 139 | while (iterator < end) | 
|  | 140 | { | 
|  | 141 | // Note keyword name | 
|  | 142 | std::string kw(iterator, iterator + lengths::KW_NAME); | 
|  | 143 |  | 
|  | 144 | // Check if the Keyword starts with '#' | 
|  | 145 | char kwNameStart = *iterator; | 
|  | 146 | std::advance(iterator, lengths::KW_NAME); | 
|  | 147 |  | 
|  | 148 | // if keyword starts with # | 
|  | 149 | if (POUND_KW == kwNameStart) | 
|  | 150 | { | 
|  | 151 | // Note existing keyword data length | 
|  | 152 | dataLength = readUInt16LE(iterator); | 
|  | 153 |  | 
|  | 154 | // Jump past 2Byte keyword length + data | 
|  | 155 | std::advance(iterator, sizeof(PoundKwSize)); | 
|  | 156 | } | 
|  | 157 | else | 
|  | 158 | { | 
|  | 159 | // Note existing keyword data length | 
|  | 160 | dataLength = *iterator; | 
|  | 161 |  | 
|  | 162 | // Jump past keyword length and data | 
|  | 163 | std::advance(iterator, sizeof(KwSize)); | 
|  | 164 | } | 
|  | 165 |  | 
|  | 166 | if (thisRecord.recKWd == kw) | 
|  | 167 | { | 
| SunnySrivastava1984 | 6d8314d | 2020-05-15 09:34:58 -0500 | [diff] [blame] | 168 | thisRecord.kwDataOffset = std::distance(vpdFile.cbegin(), iterator); | 
| SunnySrivastava1984 | f6d541e | 2020-02-04 12:50:40 -0600 | [diff] [blame] | 169 | thisRecord.kwdDataLength = dataLength; | 
| SunnySrivastava1984 | f6d541e | 2020-02-04 12:50:40 -0600 | [diff] [blame] | 170 | return; | 
|  | 171 | } | 
|  | 172 |  | 
|  | 173 | // jump the data of current kwd to point to next kwd name | 
|  | 174 | std::advance(iterator, dataLength); | 
|  | 175 | } | 
|  | 176 |  | 
|  | 177 | throw std::runtime_error("Keyword not found"); | 
|  | 178 | } | 
|  | 179 |  | 
|  | 180 | void EditorImpl::updateRecordECC() | 
|  | 181 | { | 
| SunnySrivastava1984 | 6d8314d | 2020-05-15 09:34:58 -0500 | [diff] [blame] | 182 | auto itrToRecordData = vpdFile.cbegin(); | 
|  | 183 | std::advance(itrToRecordData, thisRecord.recOffset); | 
| SunnySrivastava1984 | f6d541e | 2020-02-04 12:50:40 -0600 | [diff] [blame] | 184 |  | 
| SunnySrivastava1984 | 6d8314d | 2020-05-15 09:34:58 -0500 | [diff] [blame] | 185 | auto itrToRecordECC = vpdFile.cbegin(); | 
|  | 186 | std::advance(itrToRecordECC, thisRecord.recECCoffset); | 
| SunnySrivastava1984 | f6d541e | 2020-02-04 12:50:40 -0600 | [diff] [blame] | 187 |  | 
|  | 188 | auto l_status = vpdecc_create_ecc( | 
| SunnySrivastava1984 | 6d8314d | 2020-05-15 09:34:58 -0500 | [diff] [blame] | 189 | const_cast<uint8_t*>(&itrToRecordData[0]), thisRecord.recSize, | 
|  | 190 | const_cast<uint8_t*>(&itrToRecordECC[0]), &thisRecord.recECCLength); | 
| SunnySrivastava1984 | f6d541e | 2020-02-04 12:50:40 -0600 | [diff] [blame] | 191 | if (l_status != VPD_ECC_OK) | 
|  | 192 | { | 
|  | 193 | throw std::runtime_error("Ecc update failed"); | 
|  | 194 | } | 
|  | 195 |  | 
| SunnySrivastava1984 | 6d8314d | 2020-05-15 09:34:58 -0500 | [diff] [blame] | 196 | auto end = itrToRecordECC; | 
| SunnySrivastava1984 | f6d541e | 2020-02-04 12:50:40 -0600 | [diff] [blame] | 197 | std::advance(end, thisRecord.recECCLength); | 
|  | 198 |  | 
| SunnySrivastava1984 | a0d460e | 2020-06-03 07:49:26 -0500 | [diff] [blame] | 199 | #ifndef ManagerTest | 
| SunnySrivastava1984 | e12b181 | 2020-05-26 02:23:11 -0500 | [diff] [blame] | 200 | vpdFileStream.seekp(startOffset + thisRecord.recECCoffset, std::ios::beg); | 
| SunnySrivastava1984 | 6d8314d | 2020-05-15 09:34:58 -0500 | [diff] [blame] | 201 | std::copy(itrToRecordECC, end, | 
| SunnySrivastava1984 | f6d541e | 2020-02-04 12:50:40 -0600 | [diff] [blame] | 202 | std::ostreambuf_iterator<char>(vpdFileStream)); | 
| SunnySrivastava1984 | a0d460e | 2020-06-03 07:49:26 -0500 | [diff] [blame] | 203 | #endif | 
| SunnySrivastava1984 | f6d541e | 2020-02-04 12:50:40 -0600 | [diff] [blame] | 204 | } | 
|  | 205 |  | 
|  | 206 | auto EditorImpl::getValue(offsets::Offsets offset) | 
|  | 207 | { | 
| SunnySrivastava1984 | 6d8314d | 2020-05-15 09:34:58 -0500 | [diff] [blame] | 208 | auto itr = vpdFile.cbegin(); | 
|  | 209 | std::advance(itr, offset); | 
|  | 210 | LE2ByteData lowByte = *itr; | 
|  | 211 | LE2ByteData highByte = *(itr + 1); | 
| SunnySrivastava1984 | f6d541e | 2020-02-04 12:50:40 -0600 | [diff] [blame] | 212 | lowByte |= (highByte << 8); | 
|  | 213 |  | 
|  | 214 | return lowByte; | 
|  | 215 | } | 
|  | 216 |  | 
| girik | 18bb985 | 2022-11-16 05:48:13 -0600 | [diff] [blame^] | 217 | void EditorImpl::checkRecordData() | 
|  | 218 | { | 
|  | 219 | auto itrToRecordData = vpdFile.cbegin(); | 
|  | 220 | std::advance(itrToRecordData, thisRecord.recOffset); | 
|  | 221 |  | 
|  | 222 | auto itrToRecordECC = vpdFile.cbegin(); | 
|  | 223 | std::advance(itrToRecordECC, thisRecord.recECCoffset); | 
|  | 224 |  | 
|  | 225 | checkECC(itrToRecordData, itrToRecordECC, thisRecord.recSize, | 
|  | 226 | thisRecord.recECCLength); | 
|  | 227 | } | 
|  | 228 |  | 
| SunnySrivastava1984 | 6d8314d | 2020-05-15 09:34:58 -0500 | [diff] [blame] | 229 | void EditorImpl::checkECC(Binary::const_iterator& itrToRecData, | 
|  | 230 | Binary::const_iterator& itrToECCData, | 
| SunnySrivastava1984 | f6d541e | 2020-02-04 12:50:40 -0600 | [diff] [blame] | 231 | RecordLength recLength, ECCLength eccLength) | 
|  | 232 | { | 
|  | 233 | auto l_status = | 
| SunnySrivastava1984 | 6d8314d | 2020-05-15 09:34:58 -0500 | [diff] [blame] | 234 | vpdecc_check_data(const_cast<uint8_t*>(&itrToRecData[0]), recLength, | 
|  | 235 | const_cast<uint8_t*>(&itrToECCData[0]), eccLength); | 
|  | 236 |  | 
| girik | 18bb985 | 2022-11-16 05:48:13 -0600 | [diff] [blame^] | 237 | if (l_status == VPD_ECC_CORRECTABLE_DATA) | 
| SunnySrivastava1984 | f6d541e | 2020-02-04 12:50:40 -0600 | [diff] [blame] | 238 | { | 
| girik | 18bb985 | 2022-11-16 05:48:13 -0600 | [diff] [blame^] | 239 | try | 
|  | 240 | { | 
|  | 241 | if (vpdFileStream.is_open()) | 
|  | 242 | { | 
|  | 243 | vpdFileStream.seekp(startOffset + thisRecord.recOffset, | 
|  | 244 | std::ios::beg); | 
|  | 245 | auto end = itrToRecData; | 
|  | 246 | std::advance(end, recLength); | 
|  | 247 | std::copy(itrToRecData, end, | 
|  | 248 | std::ostreambuf_iterator<char>(vpdFileStream)); | 
|  | 249 | } | 
|  | 250 | else | 
|  | 251 | { | 
|  | 252 | throw std::runtime_error("Ecc correction failed"); | 
|  | 253 | } | 
|  | 254 | } | 
|  | 255 | catch (const std::fstream::failure& e) | 
|  | 256 | { | 
|  | 257 | std::cout << "Error while operating on file with exception"; | 
|  | 258 | throw std::runtime_error("Ecc correction failed"); | 
|  | 259 | } | 
|  | 260 | } | 
|  | 261 | else if (l_status != VPD_ECC_OK) | 
|  | 262 | { | 
|  | 263 | throw std::runtime_error("Ecc check failed"); | 
| SunnySrivastava1984 | f6d541e | 2020-02-04 12:50:40 -0600 | [diff] [blame] | 264 | } | 
|  | 265 | } | 
|  | 266 |  | 
|  | 267 | void EditorImpl::readVTOC() | 
|  | 268 | { | 
|  | 269 | // read VTOC offset | 
|  | 270 | RecordOffset tocOffset = getValue(offsets::VTOC_PTR); | 
|  | 271 |  | 
|  | 272 | // read VTOC record length | 
|  | 273 | RecordLength tocLength = getValue(offsets::VTOC_REC_LEN); | 
|  | 274 |  | 
|  | 275 | // read TOC ecc offset | 
|  | 276 | ECCOffset tocECCOffset = getValue(offsets::VTOC_ECC_OFF); | 
|  | 277 |  | 
|  | 278 | // read TOC ecc length | 
|  | 279 | ECCLength tocECCLength = getValue(offsets::VTOC_ECC_LEN); | 
|  | 280 |  | 
| SunnySrivastava1984 | 6d8314d | 2020-05-15 09:34:58 -0500 | [diff] [blame] | 281 | auto itrToRecord = vpdFile.cbegin(); | 
|  | 282 | std::advance(itrToRecord, tocOffset); | 
| SunnySrivastava1984 | f6d541e | 2020-02-04 12:50:40 -0600 | [diff] [blame] | 283 |  | 
| SunnySrivastava1984 | 6d8314d | 2020-05-15 09:34:58 -0500 | [diff] [blame] | 284 | auto iteratorToECC = vpdFile.cbegin(); | 
|  | 285 | std::advance(iteratorToECC, tocECCOffset); | 
| SunnySrivastava1984 | f6d541e | 2020-02-04 12:50:40 -0600 | [diff] [blame] | 286 |  | 
| SunnySrivastava1984 | 6d8314d | 2020-05-15 09:34:58 -0500 | [diff] [blame] | 287 | // validate ecc for the record | 
|  | 288 | checkECC(itrToRecord, iteratorToECC, tocLength, tocECCLength); | 
| SunnySrivastava1984 | f6d541e | 2020-02-04 12:50:40 -0600 | [diff] [blame] | 289 |  | 
|  | 290 | // to get to the record name. | 
| SunnySrivastava1984 | 6d8314d | 2020-05-15 09:34:58 -0500 | [diff] [blame] | 291 | std::advance(itrToRecord, sizeof(RecordId) + sizeof(RecordSize) + | 
|  | 292 | // Skip past the RT keyword, which contains | 
|  | 293 | // the record name. | 
|  | 294 | lengths::KW_NAME + sizeof(KwSize)); | 
| SunnySrivastava1984 | f6d541e | 2020-02-04 12:50:40 -0600 | [diff] [blame] | 295 |  | 
| SunnySrivastava1984 | 6d8314d | 2020-05-15 09:34:58 -0500 | [diff] [blame] | 296 | std::string recordName(itrToRecord, itrToRecord + lengths::RECORD_NAME); | 
| SunnySrivastava1984 | f6d541e | 2020-02-04 12:50:40 -0600 | [diff] [blame] | 297 |  | 
|  | 298 | if ("VTOC" != recordName) | 
|  | 299 | { | 
|  | 300 | throw std::runtime_error("VTOC record not found"); | 
|  | 301 | } | 
|  | 302 |  | 
| SunnySrivastava1984 | f6d541e | 2020-02-04 12:50:40 -0600 | [diff] [blame] | 303 | // jump to length of PT kwd | 
| SunnySrivastava1984 | 6d8314d | 2020-05-15 09:34:58 -0500 | [diff] [blame] | 304 | std::advance(itrToRecord, lengths::RECORD_NAME + lengths::KW_NAME); | 
| SunnySrivastava1984 | f6d541e | 2020-02-04 12:50:40 -0600 | [diff] [blame] | 305 |  | 
|  | 306 | // Note size of PT | 
| SunnySrivastava1984 | 6d8314d | 2020-05-15 09:34:58 -0500 | [diff] [blame] | 307 | Byte ptLen = *itrToRecord; | 
|  | 308 | std::advance(itrToRecord, 1); | 
| SunnySrivastava1984 | f6d541e | 2020-02-04 12:50:40 -0600 | [diff] [blame] | 309 |  | 
| SunnySrivastava1984 | 6d8314d | 2020-05-15 09:34:58 -0500 | [diff] [blame] | 310 | checkPTForRecord(itrToRecord, ptLen); | 
| SunnySrivastava1984 | f6d541e | 2020-02-04 12:50:40 -0600 | [diff] [blame] | 311 | } | 
|  | 312 |  | 
| SunnySrivastava1984 | d076da8 | 2020-03-05 05:33:35 -0600 | [diff] [blame] | 313 | template <typename T> | 
|  | 314 | void EditorImpl::makeDbusCall(const std::string& object, | 
|  | 315 | const std::string& interface, | 
|  | 316 | const std::string& property, | 
|  | 317 | const std::variant<T>& data) | 
|  | 318 | { | 
|  | 319 | auto bus = sdbusplus::bus::new_default(); | 
| SunnySrivastava1984 | a739259 | 2020-03-09 10:19:33 -0500 | [diff] [blame] | 320 | auto properties = | 
|  | 321 | bus.new_method_call(INVENTORY_MANAGER_SERVICE, object.c_str(), | 
|  | 322 | "org.freedesktop.DBus.Properties", "Set"); | 
| SunnySrivastava1984 | d076da8 | 2020-03-05 05:33:35 -0600 | [diff] [blame] | 323 | properties.append(interface); | 
|  | 324 | properties.append(property); | 
|  | 325 | properties.append(data); | 
|  | 326 |  | 
|  | 327 | auto result = bus.call(properties); | 
|  | 328 |  | 
|  | 329 | if (result.is_method_error()) | 
|  | 330 | { | 
|  | 331 | throw std::runtime_error("bus call failed"); | 
|  | 332 | } | 
|  | 333 | } | 
|  | 334 |  | 
| SunnySrivastava1984 | b421bfd | 2020-03-02 08:59:32 -0600 | [diff] [blame] | 335 | void EditorImpl::processAndUpdateCI(const std::string& objectPath) | 
|  | 336 | { | 
| Alpana Kumari | 414d5ae | 2021-03-04 21:06:35 +0000 | [diff] [blame] | 337 | inventory::ObjectMap objects; | 
| SunnySrivastava1984 | b421bfd | 2020-03-02 08:59:32 -0600 | [diff] [blame] | 338 | for (auto& commonInterface : jsonFile["commonInterfaces"].items()) | 
|  | 339 | { | 
|  | 340 | for (auto& ciPropertyList : commonInterface.value().items()) | 
|  | 341 | { | 
| SunnySrivastava1984 | d076da8 | 2020-03-05 05:33:35 -0600 | [diff] [blame] | 342 | if (ciPropertyList.value().type() == | 
|  | 343 | nlohmann::json::value_t::object) | 
| SunnySrivastava1984 | b421bfd | 2020-03-02 08:59:32 -0600 | [diff] [blame] | 344 | { | 
| SunnySrivastava1984 | d076da8 | 2020-03-05 05:33:35 -0600 | [diff] [blame] | 345 | if ((ciPropertyList.value().value("recordName", "") == | 
|  | 346 | thisRecord.recName) && | 
|  | 347 | (ciPropertyList.value().value("keywordName", "") == | 
|  | 348 | thisRecord.recKWd)) | 
|  | 349 | { | 
| Alpana Kumari | 414d5ae | 2021-03-04 21:06:35 +0000 | [diff] [blame] | 350 | inventory::PropertyMap prop; | 
|  | 351 | inventory::InterfaceMap interfaces; | 
| SunnySrivastava1984 | d076da8 | 2020-03-05 05:33:35 -0600 | [diff] [blame] | 352 | std::string kwdData(thisRecord.kwdUpdatedData.begin(), | 
|  | 353 | thisRecord.kwdUpdatedData.end()); | 
|  | 354 |  | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 355 | prop.emplace(ciPropertyList.key(), std::move(kwdData)); | 
|  | 356 | interfaces.emplace(commonInterface.key(), std::move(prop)); | 
|  | 357 | objects.emplace(objectPath, std::move(interfaces)); | 
| SunnySrivastava1984 | d076da8 | 2020-03-05 05:33:35 -0600 | [diff] [blame] | 358 | } | 
| SunnySrivastava1984 | b421bfd | 2020-03-02 08:59:32 -0600 | [diff] [blame] | 359 | } | 
|  | 360 | } | 
|  | 361 | } | 
| Alpana Kumari | 414d5ae | 2021-03-04 21:06:35 +0000 | [diff] [blame] | 362 | // Notify PIM | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 363 | common::utility::callPIM(std::move(objects)); | 
| SunnySrivastava1984 | b421bfd | 2020-03-02 08:59:32 -0600 | [diff] [blame] | 364 | } | 
|  | 365 |  | 
|  | 366 | void EditorImpl::processAndUpdateEI(const nlohmann::json& Inventory, | 
|  | 367 | const inventory::Path& objPath) | 
|  | 368 | { | 
| Alpana Kumari | 414d5ae | 2021-03-04 21:06:35 +0000 | [diff] [blame] | 369 | inventory::ObjectMap objects; | 
| SunnySrivastava1984 | b421bfd | 2020-03-02 08:59:32 -0600 | [diff] [blame] | 370 | for (const auto& extraInterface : Inventory["extraInterfaces"].items()) | 
|  | 371 | { | 
|  | 372 | if (extraInterface.value() != NULL) | 
|  | 373 | { | 
|  | 374 | for (const auto& eiPropertyList : extraInterface.value().items()) | 
|  | 375 | { | 
| SunnySrivastava1984 | d076da8 | 2020-03-05 05:33:35 -0600 | [diff] [blame] | 376 | if (eiPropertyList.value().type() == | 
|  | 377 | nlohmann::json::value_t::object) | 
| SunnySrivastava1984 | b421bfd | 2020-03-02 08:59:32 -0600 | [diff] [blame] | 378 | { | 
| SunnySrivastava1984 | d076da8 | 2020-03-05 05:33:35 -0600 | [diff] [blame] | 379 | if ((eiPropertyList.value().value("recordName", "") == | 
|  | 380 | thisRecord.recName) && | 
|  | 381 | ((eiPropertyList.value().value("keywordName", "") == | 
|  | 382 | thisRecord.recKWd))) | 
|  | 383 | { | 
| Alpana Kumari | 414d5ae | 2021-03-04 21:06:35 +0000 | [diff] [blame] | 384 | inventory::PropertyMap prop; | 
|  | 385 | inventory::InterfaceMap interfaces; | 
| SunnySrivastava1984 | d076da8 | 2020-03-05 05:33:35 -0600 | [diff] [blame] | 386 | std::string kwdData(thisRecord.kwdUpdatedData.begin(), | 
|  | 387 | thisRecord.kwdUpdatedData.end()); | 
| Alpana Kumari | 414d5ae | 2021-03-04 21:06:35 +0000 | [diff] [blame] | 388 | encodeKeyword(kwdData, eiPropertyList.value().value( | 
|  | 389 | "encoding", "")); | 
|  | 390 |  | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 391 | prop.emplace(eiPropertyList.key(), std::move(kwdData)); | 
|  | 392 | interfaces.emplace(extraInterface.key(), | 
|  | 393 | std::move(prop)); | 
|  | 394 | objects.emplace(objPath, std::move(interfaces)); | 
| SunnySrivastava1984 | d076da8 | 2020-03-05 05:33:35 -0600 | [diff] [blame] | 395 | } | 
| SunnySrivastava1984 | b421bfd | 2020-03-02 08:59:32 -0600 | [diff] [blame] | 396 | } | 
|  | 397 | } | 
|  | 398 | } | 
|  | 399 | } | 
| Alpana Kumari | 414d5ae | 2021-03-04 21:06:35 +0000 | [diff] [blame] | 400 | // Notify PIM | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 401 | common::utility::callPIM(std::move(objects)); | 
| SunnySrivastava1984 | b421bfd | 2020-03-02 08:59:32 -0600 | [diff] [blame] | 402 | } | 
|  | 403 |  | 
|  | 404 | void EditorImpl::updateCache() | 
|  | 405 | { | 
|  | 406 | const std::vector<nlohmann::json>& groupEEPROM = | 
|  | 407 | jsonFile["frus"][vpdFilePath].get_ref<const nlohmann::json::array_t&>(); | 
|  | 408 |  | 
| Alpana Kumari | 414d5ae | 2021-03-04 21:06:35 +0000 | [diff] [blame] | 409 | inventory::ObjectMap objects; | 
| SunnySrivastava1984 | b421bfd | 2020-03-02 08:59:32 -0600 | [diff] [blame] | 410 | // iterate through all the inventories for this file path | 
|  | 411 | for (const auto& singleInventory : groupEEPROM) | 
|  | 412 | { | 
| Alpana Kumari | 414d5ae | 2021-03-04 21:06:35 +0000 | [diff] [blame] | 413 | inventory::PropertyMap prop; | 
|  | 414 | inventory::InterfaceMap interfaces; | 
| SunnySrivastava1984 | d076da8 | 2020-03-05 05:33:35 -0600 | [diff] [blame] | 415 | // by default inherit property is true | 
|  | 416 | bool isInherit = true; | 
|  | 417 |  | 
|  | 418 | if (singleInventory.find("inherit") != singleInventory.end()) | 
| SunnySrivastava1984 | b421bfd | 2020-03-02 08:59:32 -0600 | [diff] [blame] | 419 | { | 
| SunnySrivastava1984 | d076da8 | 2020-03-05 05:33:35 -0600 | [diff] [blame] | 420 | isInherit = singleInventory["inherit"].get<bool>(); | 
|  | 421 | } | 
|  | 422 |  | 
|  | 423 | if (isInherit) | 
|  | 424 | { | 
| Santosh Puranik | 32c4650 | 2022-02-10 08:55:07 +0530 | [diff] [blame] | 425 | prop.emplace(thisRecord.recKWd, thisRecord.kwdUpdatedData); | 
|  | 426 | interfaces.emplace( | 
|  | 427 | (IPZ_INTERFACE + (std::string) "." + thisRecord.recName), | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 428 | std::move(prop)); | 
| Santosh Puranik | 32c4650 | 2022-02-10 08:55:07 +0530 | [diff] [blame] | 429 | objects.emplace( | 
|  | 430 | (singleInventory["inventoryPath"].get<std::string>()), | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 431 | std::move(interfaces)); | 
| SunnySrivastava1984 | d076da8 | 2020-03-05 05:33:35 -0600 | [diff] [blame] | 432 |  | 
|  | 433 | // process Common interface | 
| SunnySrivastava1984 | b421bfd | 2020-03-02 08:59:32 -0600 | [diff] [blame] | 434 | processAndUpdateCI(singleInventory["inventoryPath"] | 
|  | 435 | .get_ref<const nlohmann::json::string_t&>()); | 
|  | 436 | } | 
|  | 437 |  | 
| Santosh Puranik | 32c4650 | 2022-02-10 08:55:07 +0530 | [diff] [blame] | 438 | // process extra interfaces | 
|  | 439 | processAndUpdateEI(singleInventory, | 
|  | 440 | singleInventory["inventoryPath"] | 
|  | 441 | .get_ref<const nlohmann::json::string_t&>()); | 
| Sunny Srivastava | 26d6c14 | 2021-11-03 15:19:02 -0500 | [diff] [blame] | 442 |  | 
|  | 443 | // check if we need to copy some specific records in this case. | 
|  | 444 | if (singleInventory.find("copyRecords") != singleInventory.end()) | 
|  | 445 | { | 
|  | 446 | if (find(singleInventory["copyRecords"].begin(), | 
|  | 447 | singleInventory["copyRecords"].end(), | 
|  | 448 | thisRecord.recName) != | 
|  | 449 | singleInventory["copyRecords"].end()) | 
|  | 450 | { | 
|  | 451 | prop.emplace(thisRecord.recKWd, thisRecord.kwdUpdatedData); | 
|  | 452 | interfaces.emplace( | 
|  | 453 | (IPZ_INTERFACE + std::string{"."} + thisRecord.recName), | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 454 | std::move(prop)); | 
| Sunny Srivastava | 26d6c14 | 2021-11-03 15:19:02 -0500 | [diff] [blame] | 455 | objects.emplace( | 
|  | 456 | (singleInventory["inventoryPath"].get<std::string>()), | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 457 | std::move(interfaces)); | 
| Sunny Srivastava | 26d6c14 | 2021-11-03 15:19:02 -0500 | [diff] [blame] | 458 | } | 
|  | 459 | } | 
| SunnySrivastava1984 | b421bfd | 2020-03-02 08:59:32 -0600 | [diff] [blame] | 460 | } | 
| Alpana Kumari | 414d5ae | 2021-03-04 21:06:35 +0000 | [diff] [blame] | 461 | // Notify PIM | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 462 | common::utility::callPIM(std::move(objects)); | 
| SunnySrivastava1984 | b421bfd | 2020-03-02 08:59:32 -0600 | [diff] [blame] | 463 | } | 
|  | 464 |  | 
| SunnySrivastava1984 | 4330654 | 2020-04-01 02:50:20 -0500 | [diff] [blame] | 465 | void EditorImpl::expandLocationCode(const std::string& locationCodeType) | 
|  | 466 | { | 
|  | 467 | std::string propertyFCorTM{}; | 
|  | 468 | std::string propertySE{}; | 
|  | 469 |  | 
|  | 470 | if (locationCodeType == "fcs") | 
|  | 471 | { | 
|  | 472 | propertyFCorTM = | 
|  | 473 | readBusProperty(SYSTEM_OBJECT, "com.ibm.ipzvpd.VCEN", "FC"); | 
|  | 474 | propertySE = | 
|  | 475 | readBusProperty(SYSTEM_OBJECT, "com.ibm.ipzvpd.VCEN", "SE"); | 
|  | 476 | } | 
|  | 477 | else if (locationCodeType == "mts") | 
|  | 478 | { | 
|  | 479 | propertyFCorTM = | 
|  | 480 | readBusProperty(SYSTEM_OBJECT, "com.ibm.ipzvpd.VSYS", "TM"); | 
|  | 481 | propertySE = | 
|  | 482 | readBusProperty(SYSTEM_OBJECT, "com.ibm.ipzvpd.VSYS", "SE"); | 
|  | 483 | } | 
|  | 484 |  | 
|  | 485 | const nlohmann::json& groupFRUS = | 
|  | 486 | jsonFile["frus"].get_ref<const nlohmann::json::object_t&>(); | 
| Alpana Kumari | 414d5ae | 2021-03-04 21:06:35 +0000 | [diff] [blame] | 487 | inventory::ObjectMap objects; | 
|  | 488 |  | 
| SunnySrivastava1984 | 4330654 | 2020-04-01 02:50:20 -0500 | [diff] [blame] | 489 | for (const auto& itemFRUS : groupFRUS.items()) | 
|  | 490 | { | 
|  | 491 | const std::vector<nlohmann::json>& groupEEPROM = | 
|  | 492 | itemFRUS.value().get_ref<const nlohmann::json::array_t&>(); | 
|  | 493 | for (const auto& itemEEPROM : groupEEPROM) | 
|  | 494 | { | 
| Alpana Kumari | 414d5ae | 2021-03-04 21:06:35 +0000 | [diff] [blame] | 495 | inventory::PropertyMap prop; | 
|  | 496 | inventory::InterfaceMap interfaces; | 
|  | 497 | const auto& objectPath = itemEEPROM["inventoryPath"]; | 
|  | 498 | sdbusplus::message::object_path object(objectPath); | 
|  | 499 |  | 
| SunnySrivastava1984 | 4330654 | 2020-04-01 02:50:20 -0500 | [diff] [blame] | 500 | // check if the given item implements location code interface | 
| Alpana Kumari | 414d5ae | 2021-03-04 21:06:35 +0000 | [diff] [blame] | 501 | if (itemEEPROM["extraInterfaces"].find(IBM_LOCATION_CODE_INF) != | 
| SunnySrivastava1984 | 4330654 | 2020-04-01 02:50:20 -0500 | [diff] [blame] | 502 | itemEEPROM["extraInterfaces"].end()) | 
|  | 503 | { | 
|  | 504 | const std::string& unexpandedLocationCode = | 
| Alpana Kumari | 414d5ae | 2021-03-04 21:06:35 +0000 | [diff] [blame] | 505 | itemEEPROM["extraInterfaces"][IBM_LOCATION_CODE_INF] | 
| SunnySrivastava1984 | 4330654 | 2020-04-01 02:50:20 -0500 | [diff] [blame] | 506 | ["LocationCode"] | 
|  | 507 | .get_ref<const nlohmann::json::string_t&>(); | 
|  | 508 | std::size_t idx = unexpandedLocationCode.find(locationCodeType); | 
|  | 509 | if (idx != std::string::npos) | 
|  | 510 | { | 
| Alpana Kumari | 414d5ae | 2021-03-04 21:06:35 +0000 | [diff] [blame] | 511 | std::string expandedLocationCode(unexpandedLocationCode); | 
| SunnySrivastava1984 | 4330654 | 2020-04-01 02:50:20 -0500 | [diff] [blame] | 512 |  | 
|  | 513 | if (locationCodeType == "fcs") | 
|  | 514 | { | 
| Alpana Kumari | 414d5ae | 2021-03-04 21:06:35 +0000 | [diff] [blame] | 515 | expandedLocationCode.replace( | 
| SunnySrivastava1984 | 4330654 | 2020-04-01 02:50:20 -0500 | [diff] [blame] | 516 | idx, 3, | 
|  | 517 | propertyFCorTM.substr(0, 4) + ".ND0." + propertySE); | 
|  | 518 | } | 
|  | 519 | else if (locationCodeType == "mts") | 
|  | 520 | { | 
|  | 521 | std::replace(propertyFCorTM.begin(), | 
|  | 522 | propertyFCorTM.end(), '-', '.'); | 
| Alpana Kumari | 414d5ae | 2021-03-04 21:06:35 +0000 | [diff] [blame] | 523 | expandedLocationCode.replace( | 
| SunnySrivastava1984 | 4330654 | 2020-04-01 02:50:20 -0500 | [diff] [blame] | 524 | idx, 3, propertyFCorTM + "." + propertySE); | 
|  | 525 | } | 
|  | 526 |  | 
| Alpana Kumari | 414d5ae | 2021-03-04 21:06:35 +0000 | [diff] [blame] | 527 | // update the DBUS interface COM as well as XYZ path | 
|  | 528 | prop.emplace("LocationCode", expandedLocationCode); | 
|  | 529 | // TODO depricate this com.ibm interface later | 
|  | 530 | interfaces.emplace(IBM_LOCATION_CODE_INF, prop); | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 531 | interfaces.emplace(XYZ_LOCATION_CODE_INF, std::move(prop)); | 
| SunnySrivastava1984 | 4330654 | 2020-04-01 02:50:20 -0500 | [diff] [blame] | 532 | } | 
|  | 533 | } | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 534 | objects.emplace(std::move(object), std::move(interfaces)); | 
| SunnySrivastava1984 | 4330654 | 2020-04-01 02:50:20 -0500 | [diff] [blame] | 535 | } | 
|  | 536 | } | 
| Alpana Kumari | 414d5ae | 2021-03-04 21:06:35 +0000 | [diff] [blame] | 537 | // Notify PIM | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 538 | common::utility::callPIM(std::move(objects)); | 
| SunnySrivastava1984 | 4330654 | 2020-04-01 02:50:20 -0500 | [diff] [blame] | 539 | } | 
|  | 540 |  | 
| Sunny Srivastava | f31a91b | 2022-06-09 08:11:29 -0500 | [diff] [blame] | 541 | #ifndef ManagerTest | 
|  | 542 | static void enableRebootGuard() | 
|  | 543 | { | 
|  | 544 | try | 
|  | 545 | { | 
|  | 546 | auto bus = sdbusplus::bus::new_default(); | 
|  | 547 | auto method = bus.new_method_call( | 
|  | 548 | "org.freedesktop.systemd1", "/org/freedesktop/systemd1", | 
|  | 549 | "org.freedesktop.systemd1.Manager", "StartUnit"); | 
|  | 550 | method.append("reboot-guard-enable.service", "replace"); | 
|  | 551 | bus.call_noreply(method); | 
|  | 552 | } | 
| Patrick Williams | 7a975f0 | 2022-12-07 03:19:53 -0600 | [diff] [blame] | 553 | catch (const sdbusplus::exception_t& e) | 
| Sunny Srivastava | f31a91b | 2022-06-09 08:11:29 -0500 | [diff] [blame] | 554 | { | 
|  | 555 | std::string errMsg = | 
|  | 556 | "Bus call to enable BMC reboot failed for reason: "; | 
|  | 557 | errMsg += e.what(); | 
|  | 558 |  | 
|  | 559 | throw std::runtime_error(errMsg); | 
|  | 560 | } | 
|  | 561 | } | 
|  | 562 |  | 
|  | 563 | static void disableRebootGuard() | 
|  | 564 | { | 
|  | 565 | try | 
|  | 566 | { | 
|  | 567 | auto bus = sdbusplus::bus::new_default(); | 
|  | 568 | auto method = bus.new_method_call( | 
|  | 569 | "org.freedesktop.systemd1", "/org/freedesktop/systemd1", | 
|  | 570 | "org.freedesktop.systemd1.Manager", "StartUnit"); | 
|  | 571 | method.append("reboot-guard-disable.service", "replace"); | 
|  | 572 | bus.call_noreply(method); | 
|  | 573 | } | 
| Patrick Williams | 7a975f0 | 2022-12-07 03:19:53 -0600 | [diff] [blame] | 574 | catch (const sdbusplus::exception_t& e) | 
| Sunny Srivastava | f31a91b | 2022-06-09 08:11:29 -0500 | [diff] [blame] | 575 | { | 
|  | 576 | using namespace phosphor::logging; | 
|  | 577 | using InternalFailure = | 
|  | 578 | sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure; | 
|  | 579 |  | 
|  | 580 | std::string errMsg = | 
|  | 581 | "Bus call to disable BMC reboot failed for reason: "; | 
|  | 582 | errMsg += e.what(); | 
|  | 583 |  | 
|  | 584 | log<level::ERR>("Disable boot guard failed"); | 
|  | 585 | elog<InternalFailure>(); | 
|  | 586 |  | 
|  | 587 | throw std::runtime_error(errMsg); | 
|  | 588 | } | 
|  | 589 | } | 
|  | 590 | #endif | 
|  | 591 |  | 
| Santosh Puranik | a0b2391 | 2022-02-10 13:37:09 +0530 | [diff] [blame] | 592 | void EditorImpl::updateKeyword(const Binary& kwdData, uint32_t offset, | 
|  | 593 | const bool& updCache) | 
| SunnySrivastava1984 | f6d541e | 2020-02-04 12:50:40 -0600 | [diff] [blame] | 594 | { | 
| Sunny Srivastava | f31a91b | 2022-06-09 08:11:29 -0500 | [diff] [blame] | 595 | try | 
|  | 596 | { | 
|  | 597 | startOffset = offset; | 
| SunnySrivastava1984 | a0d460e | 2020-06-03 07:49:26 -0500 | [diff] [blame] | 598 | #ifndef ManagerTest | 
| Sunny Srivastava | f31a91b | 2022-06-09 08:11:29 -0500 | [diff] [blame] | 599 | // Restrict BMC from rebooting when VPD is being written. This will | 
|  | 600 | // prevent any data/ECC corruption in case BMC reboots while VPD update. | 
|  | 601 | enableRebootGuard(); | 
| SunnySrivastava1984 | a0d460e | 2020-06-03 07:49:26 -0500 | [diff] [blame] | 602 |  | 
| Sunny Srivastava | f31a91b | 2022-06-09 08:11:29 -0500 | [diff] [blame] | 603 | // TODO: Figure out a better way to get max possible VPD size. | 
|  | 604 | Binary completeVPDFile; | 
|  | 605 | completeVPDFile.resize(65504); | 
|  | 606 | vpdFileStream.open(vpdFilePath, | 
|  | 607 | std::ios::in | std::ios::out | std::ios::binary); | 
| SunnySrivastava1984 | f6d541e | 2020-02-04 12:50:40 -0600 | [diff] [blame] | 608 |  | 
| Sunny Srivastava | f31a91b | 2022-06-09 08:11:29 -0500 | [diff] [blame] | 609 | vpdFileStream.seekg(startOffset, std::ios_base::cur); | 
|  | 610 | vpdFileStream.read(reinterpret_cast<char*>(&completeVPDFile[0]), 65504); | 
|  | 611 | completeVPDFile.resize(vpdFileStream.gcount()); | 
|  | 612 | vpdFileStream.clear(std::ios_base::eofbit); | 
|  | 613 |  | 
|  | 614 | vpdFile = completeVPDFile; | 
|  | 615 |  | 
|  | 616 | if (objPath.empty() && | 
|  | 617 | jsonFile["frus"].find(vpdFilePath) != jsonFile["frus"].end()) | 
|  | 618 | { | 
|  | 619 | objPath = jsonFile["frus"][vpdFilePath][0]["inventoryPath"] | 
|  | 620 | .get_ref<const nlohmann::json::string_t&>(); | 
|  | 621 | } | 
| Alpana Kumari | 920408d | 2020-05-14 00:07:03 -0500 | [diff] [blame] | 622 |  | 
| SunnySrivastava1984 | a0d460e | 2020-06-03 07:49:26 -0500 | [diff] [blame] | 623 | #else | 
| Alpana Kumari | 920408d | 2020-05-14 00:07:03 -0500 | [diff] [blame] | 624 |  | 
| Sunny Srivastava | f31a91b | 2022-06-09 08:11:29 -0500 | [diff] [blame] | 625 | Binary completeVPDFile = vpdFile; | 
| Alpana Kumari | 920408d | 2020-05-14 00:07:03 -0500 | [diff] [blame] | 626 |  | 
| SunnySrivastava1984 | a0d460e | 2020-06-03 07:49:26 -0500 | [diff] [blame] | 627 | #endif | 
| Sunny Srivastava | f31a91b | 2022-06-09 08:11:29 -0500 | [diff] [blame] | 628 | if (vpdFile.empty()) | 
| SunnySrivastava1984 | e12b181 | 2020-05-26 02:23:11 -0500 | [diff] [blame] | 629 | { | 
| Sunny Srivastava | f31a91b | 2022-06-09 08:11:29 -0500 | [diff] [blame] | 630 | throw std::runtime_error("Invalid File"); | 
| SunnySrivastava1984 | e12b181 | 2020-05-26 02:23:11 -0500 | [diff] [blame] | 631 | } | 
| Sunny Srivastava | f31a91b | 2022-06-09 08:11:29 -0500 | [diff] [blame] | 632 | auto iterator = vpdFile.cbegin(); | 
|  | 633 | std::advance(iterator, IPZ_DATA_START); | 
|  | 634 |  | 
|  | 635 | Byte vpdType = *iterator; | 
|  | 636 | if (vpdType == KW_VAL_PAIR_START_TAG) | 
| SunnySrivastava1984 | e12b181 | 2020-05-26 02:23:11 -0500 | [diff] [blame] | 637 | { | 
| Sunny Srivastava | f31a91b | 2022-06-09 08:11:29 -0500 | [diff] [blame] | 638 | // objPath should be empty only in case of test run. | 
| girik | 18bb985 | 2022-11-16 05:48:13 -0600 | [diff] [blame^] | 639 | ParserInterface* Iparser = ParserFactory::getParser( | 
|  | 640 | completeVPDFile, objPath, vpdFilePath, startOffset); | 
| Sunny Srivastava | f31a91b | 2022-06-09 08:11:29 -0500 | [diff] [blame] | 641 | IpzVpdParser* ipzParser = dynamic_cast<IpzVpdParser*>(Iparser); | 
|  | 642 |  | 
|  | 643 | try | 
| SunnySrivastava1984 | e12b181 | 2020-05-26 02:23:11 -0500 | [diff] [blame] | 644 | { | 
| Sunny Srivastava | f31a91b | 2022-06-09 08:11:29 -0500 | [diff] [blame] | 645 | if (ipzParser == nullptr) | 
|  | 646 | { | 
|  | 647 | throw std::runtime_error("Invalid cast"); | 
|  | 648 | } | 
|  | 649 |  | 
|  | 650 | ipzParser->processHeader(); | 
| SunnySrivastava1984 | e12b181 | 2020-05-26 02:23:11 -0500 | [diff] [blame] | 651 | delete ipzParser; | 
| Sunny Srivastava | f31a91b | 2022-06-09 08:11:29 -0500 | [diff] [blame] | 652 | ipzParser = nullptr; | 
|  | 653 | // ParserFactory::freeParser(Iparser); | 
|  | 654 |  | 
|  | 655 | // process VTOC for PTT rkwd | 
|  | 656 | readVTOC(); | 
|  | 657 |  | 
|  | 658 | // check record for keywrod | 
|  | 659 | checkRecordForKwd(); | 
|  | 660 |  | 
| girik | 18bb985 | 2022-11-16 05:48:13 -0600 | [diff] [blame^] | 661 | // Check Data before updating | 
|  | 662 | checkRecordData(); | 
|  | 663 |  | 
| Sunny Srivastava | f31a91b | 2022-06-09 08:11:29 -0500 | [diff] [blame] | 664 | // update the data to the file | 
|  | 665 | updateData(kwdData); | 
|  | 666 |  | 
|  | 667 | // update the ECC data for the record once data has been updated | 
|  | 668 | updateRecordECC(); | 
|  | 669 |  | 
|  | 670 | if (updCache) | 
|  | 671 | { | 
|  | 672 | #ifndef ManagerTest | 
|  | 673 | // update the cache once data has been updated | 
|  | 674 | updateCache(); | 
|  | 675 | #endif | 
|  | 676 | } | 
| SunnySrivastava1984 | e12b181 | 2020-05-26 02:23:11 -0500 | [diff] [blame] | 677 | } | 
| Sunny Srivastava | f31a91b | 2022-06-09 08:11:29 -0500 | [diff] [blame] | 678 | catch (const std::exception& e) | 
|  | 679 | { | 
|  | 680 | if (ipzParser != nullptr) | 
|  | 681 | { | 
|  | 682 | delete ipzParser; | 
|  | 683 | } | 
|  | 684 | throw std::runtime_error(e.what()); | 
|  | 685 | } | 
|  | 686 |  | 
|  | 687 | #ifndef ManagerTest | 
|  | 688 | // Once VPD data and Ecc update is done, disable BMC boot guard. | 
|  | 689 | disableRebootGuard(); | 
|  | 690 | #endif | 
|  | 691 |  | 
|  | 692 | return; | 
| SunnySrivastava1984 | e12b181 | 2020-05-26 02:23:11 -0500 | [diff] [blame] | 693 | } | 
| Sunny Srivastava | f31a91b | 2022-06-09 08:11:29 -0500 | [diff] [blame] | 694 | else | 
|  | 695 | { | 
|  | 696 | throw openpower::vpd::exceptions::VpdDataException( | 
|  | 697 | "Could not find start tag in VPD " + vpdFilePath); | 
|  | 698 | } | 
| SunnySrivastava1984 | 6d8314d | 2020-05-15 09:34:58 -0500 | [diff] [blame] | 699 | } | 
| Sunny Srivastava | f31a91b | 2022-06-09 08:11:29 -0500 | [diff] [blame] | 700 | catch (const std::exception& e) | 
| Priyanga Ramasamy | c99a0b0 | 2022-06-08 14:53:39 -0500 | [diff] [blame] | 701 | { | 
| Sunny Srivastava | f31a91b | 2022-06-09 08:11:29 -0500 | [diff] [blame] | 702 | #ifndef ManagerTest | 
|  | 703 | // Disable reboot guard. | 
|  | 704 | disableRebootGuard(); | 
|  | 705 | #endif | 
|  | 706 |  | 
|  | 707 | throw std::runtime_error(e.what()); | 
| Priyanga Ramasamy | c99a0b0 | 2022-06-08 14:53:39 -0500 | [diff] [blame] | 708 | } | 
| SunnySrivastava1984 | f6d541e | 2020-02-04 12:50:40 -0600 | [diff] [blame] | 709 | } | 
| SunnySrivastava1984 | f6d541e | 2020-02-04 12:50:40 -0600 | [diff] [blame] | 710 | } // namespace editor | 
|  | 711 | } // namespace manager | 
|  | 712 | } // namespace vpd | 
| Santosh Puranik | 32c4650 | 2022-02-10 08:55:07 +0530 | [diff] [blame] | 713 | } // namespace openpower |