blob: 30f0a415a99fba08d6fc334570714ab6a069f373 [file] [log] [blame]
SunnySrivastava1984a7392592020-03-09 10:19:33 -05001#include "config.h"
2
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -06003#include "editor_impl.hpp"
4
Alpana Kumari414d5ae2021-03-04 21:06:35 +00005#include "common_utility.hpp"
Sunny Srivastava6c71c9d2021-04-15 04:43:54 -05006#include "ibm_vpd_utils.hpp"
SunnySrivastava1984e12b1812020-05-26 02:23:11 -05007#include "ipz_parser.hpp"
8#include "parser_factory.hpp"
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -06009
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -060010#include "vpdecc/vpdecc.h"
11
SunnySrivastava1984e12b1812020-05-26 02:23:11 -050012using namespace openpower::vpd::parser::interface;
13using namespace openpower::vpd::constants;
14using namespace openpower::vpd::parser::factory;
15using namespace openpower::vpd::ipz::parser;
16
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -060017namespace openpower
18{
19namespace vpd
20{
21namespace manager
22{
23namespace editor
24{
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -060025
26void EditorImpl::checkPTForRecord(Binary::const_iterator& iterator,
27 Byte ptLength)
28{
29 // auto iterator = ptRecord.cbegin();
30 auto end = std::next(iterator, ptLength + 1);
31
32 // Look at each entry in the PT keyword for the record name
33 while (iterator < end)
34 {
35 auto stop = std::next(iterator, lengths::RECORD_NAME);
36 std::string record(iterator, stop);
37
38 if (record == thisRecord.recName)
39 {
40 // Skip record name and record type
41 std::advance(iterator, lengths::RECORD_NAME + sizeof(RecordType));
42
43 // Get record offset
44 thisRecord.recOffset = readUInt16LE(iterator);
45
46 // pass the record offset length to read record length
47 std::advance(iterator, lengths::RECORD_OFFSET);
48 thisRecord.recSize = readUInt16LE(iterator);
49
50 std::advance(iterator, lengths::RECORD_LENGTH);
51 thisRecord.recECCoffset = readUInt16LE(iterator);
52
53 ECCLength len;
54 std::advance(iterator, lengths::RECORD_ECC_OFFSET);
55 len = readUInt16LE(iterator);
56 thisRecord.recECCLength = len;
57
58 // once we find the record we don't need to look further
59 return;
60 }
61 else
62 {
63 // Jump the record
64 std::advance(iterator, lengths::RECORD_NAME + sizeof(RecordType) +
65 sizeof(RecordOffset) +
66 sizeof(RecordLength) +
67 sizeof(ECCOffset) + sizeof(ECCLength));
68 }
69 }
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -060070 // imples the record was not found
71 throw std::runtime_error("Record not found");
72}
73
SunnySrivastava19846d8314d2020-05-15 09:34:58 -050074void EditorImpl::updateData(const Binary& kwdData)
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -060075{
76 std::size_t lengthToUpdate = kwdData.size() <= thisRecord.kwdDataLength
77 ? kwdData.size()
78 : thisRecord.kwdDataLength;
79
80 auto iteratorToNewdata = kwdData.cbegin();
81 auto end = iteratorToNewdata;
82 std::advance(end, lengthToUpdate);
83
SunnySrivastava19846d8314d2020-05-15 09:34:58 -050084 // update data in file buffer as it will be needed to update ECC
85 // avoiding extra stream operation here
86 auto iteratorToKWdData = vpdFile.begin();
87 std::advance(iteratorToKWdData, thisRecord.kwDataOffset);
88 std::copy(iteratorToNewdata, end, iteratorToKWdData);
89
SunnySrivastava1984a0d460e2020-06-03 07:49:26 -050090#ifdef ManagerTest
91 auto startItr = vpdFile.begin();
92 std::advance(iteratorToKWdData, thisRecord.kwDataOffset);
93 auto endItr = startItr;
94 std::advance(endItr, thisRecord.kwdDataLength);
95
96 Binary updatedData(startItr, endItr);
97 if (updatedData == kwdData)
98 {
99 throw std::runtime_error("Data updated successfully");
100 }
101#else
102
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500103 // update data in EEPROM as well. As we will not write complete file back
SunnySrivastava1984e12b1812020-05-26 02:23:11 -0500104 vpdFileStream.seekp(startOffset + thisRecord.kwDataOffset, std::ios::beg);
Alpana Kumari920408d2020-05-14 00:07:03 -0500105
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500106 iteratorToNewdata = kwdData.cbegin();
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600107 std::copy(iteratorToNewdata, end,
108 std::ostreambuf_iterator<char>(vpdFileStream));
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500109
110 // get a hold to new data in case encoding is needed
111 thisRecord.kwdUpdatedData.resize(thisRecord.kwdDataLength);
112 auto itrToKWdData = vpdFile.cbegin();
113 std::advance(itrToKWdData, thisRecord.kwDataOffset);
114 auto kwdDataEnd = itrToKWdData;
115 std::advance(kwdDataEnd, thisRecord.kwdDataLength);
116 std::copy(itrToKWdData, kwdDataEnd, thisRecord.kwdUpdatedData.begin());
SunnySrivastava1984a0d460e2020-06-03 07:49:26 -0500117#endif
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600118}
119
120void EditorImpl::checkRecordForKwd()
121{
122 RecordOffset recOffset = thisRecord.recOffset;
123
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500124 // Amount to skip for record ID, size, and the RT keyword
125 constexpr auto skipBeg = sizeof(RecordId) + sizeof(RecordSize) +
126 lengths::KW_NAME + sizeof(KwSize);
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600127
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500128 auto iterator = vpdFile.cbegin();
129 std::advance(iterator, recOffset + skipBeg + lengths::RECORD_NAME);
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600130
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500131 auto end = iterator;
132 std::advance(end, thisRecord.recSize);
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600133 std::size_t dataLength = 0;
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500134
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600135 while (iterator < end)
136 {
137 // Note keyword name
138 std::string kw(iterator, iterator + lengths::KW_NAME);
139
140 // Check if the Keyword starts with '#'
141 char kwNameStart = *iterator;
142 std::advance(iterator, lengths::KW_NAME);
143
144 // if keyword starts with #
145 if (POUND_KW == kwNameStart)
146 {
147 // Note existing keyword data length
148 dataLength = readUInt16LE(iterator);
149
150 // Jump past 2Byte keyword length + data
151 std::advance(iterator, sizeof(PoundKwSize));
152 }
153 else
154 {
155 // Note existing keyword data length
156 dataLength = *iterator;
157
158 // Jump past keyword length and data
159 std::advance(iterator, sizeof(KwSize));
160 }
161
162 if (thisRecord.recKWd == kw)
163 {
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500164 thisRecord.kwDataOffset = std::distance(vpdFile.cbegin(), iterator);
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600165 thisRecord.kwdDataLength = dataLength;
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600166 return;
167 }
168
169 // jump the data of current kwd to point to next kwd name
170 std::advance(iterator, dataLength);
171 }
172
173 throw std::runtime_error("Keyword not found");
174}
175
176void EditorImpl::updateRecordECC()
177{
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500178 auto itrToRecordData = vpdFile.cbegin();
179 std::advance(itrToRecordData, thisRecord.recOffset);
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600180
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500181 auto itrToRecordECC = vpdFile.cbegin();
182 std::advance(itrToRecordECC, thisRecord.recECCoffset);
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600183
184 auto l_status = vpdecc_create_ecc(
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500185 const_cast<uint8_t*>(&itrToRecordData[0]), thisRecord.recSize,
186 const_cast<uint8_t*>(&itrToRecordECC[0]), &thisRecord.recECCLength);
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600187 if (l_status != VPD_ECC_OK)
188 {
189 throw std::runtime_error("Ecc update failed");
190 }
191
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500192 auto end = itrToRecordECC;
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600193 std::advance(end, thisRecord.recECCLength);
194
SunnySrivastava1984a0d460e2020-06-03 07:49:26 -0500195#ifndef ManagerTest
SunnySrivastava1984e12b1812020-05-26 02:23:11 -0500196 vpdFileStream.seekp(startOffset + thisRecord.recECCoffset, std::ios::beg);
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500197 std::copy(itrToRecordECC, end,
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600198 std::ostreambuf_iterator<char>(vpdFileStream));
SunnySrivastava1984a0d460e2020-06-03 07:49:26 -0500199#endif
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600200}
201
202auto EditorImpl::getValue(offsets::Offsets offset)
203{
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500204 auto itr = vpdFile.cbegin();
205 std::advance(itr, offset);
206 LE2ByteData lowByte = *itr;
207 LE2ByteData highByte = *(itr + 1);
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600208 lowByte |= (highByte << 8);
209
210 return lowByte;
211}
212
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500213void EditorImpl::checkECC(Binary::const_iterator& itrToRecData,
214 Binary::const_iterator& itrToECCData,
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600215 RecordLength recLength, ECCLength eccLength)
216{
217 auto l_status =
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500218 vpdecc_check_data(const_cast<uint8_t*>(&itrToRecData[0]), recLength,
219 const_cast<uint8_t*>(&itrToECCData[0]), eccLength);
220
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600221 if (l_status != VPD_ECC_OK)
222 {
223 throw std::runtime_error("Ecc check failed for VTOC");
224 }
225}
226
227void EditorImpl::readVTOC()
228{
229 // read VTOC offset
230 RecordOffset tocOffset = getValue(offsets::VTOC_PTR);
231
232 // read VTOC record length
233 RecordLength tocLength = getValue(offsets::VTOC_REC_LEN);
234
235 // read TOC ecc offset
236 ECCOffset tocECCOffset = getValue(offsets::VTOC_ECC_OFF);
237
238 // read TOC ecc length
239 ECCLength tocECCLength = getValue(offsets::VTOC_ECC_LEN);
240
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500241 auto itrToRecord = vpdFile.cbegin();
242 std::advance(itrToRecord, tocOffset);
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600243
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500244 auto iteratorToECC = vpdFile.cbegin();
245 std::advance(iteratorToECC, tocECCOffset);
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600246
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500247 // validate ecc for the record
248 checkECC(itrToRecord, iteratorToECC, tocLength, tocECCLength);
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600249
250 // to get to the record name.
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500251 std::advance(itrToRecord, sizeof(RecordId) + sizeof(RecordSize) +
252 // Skip past the RT keyword, which contains
253 // the record name.
254 lengths::KW_NAME + sizeof(KwSize));
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600255
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500256 std::string recordName(itrToRecord, itrToRecord + lengths::RECORD_NAME);
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600257
258 if ("VTOC" != recordName)
259 {
260 throw std::runtime_error("VTOC record not found");
261 }
262
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600263 // jump to length of PT kwd
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500264 std::advance(itrToRecord, lengths::RECORD_NAME + lengths::KW_NAME);
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600265
266 // Note size of PT
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500267 Byte ptLen = *itrToRecord;
268 std::advance(itrToRecord, 1);
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600269
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500270 checkPTForRecord(itrToRecord, ptLen);
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600271}
272
SunnySrivastava1984d076da82020-03-05 05:33:35 -0600273template <typename T>
274void EditorImpl::makeDbusCall(const std::string& object,
275 const std::string& interface,
276 const std::string& property,
277 const std::variant<T>& data)
278{
279 auto bus = sdbusplus::bus::new_default();
SunnySrivastava1984a7392592020-03-09 10:19:33 -0500280 auto properties =
281 bus.new_method_call(INVENTORY_MANAGER_SERVICE, object.c_str(),
282 "org.freedesktop.DBus.Properties", "Set");
SunnySrivastava1984d076da82020-03-05 05:33:35 -0600283 properties.append(interface);
284 properties.append(property);
285 properties.append(data);
286
287 auto result = bus.call(properties);
288
289 if (result.is_method_error())
290 {
291 throw std::runtime_error("bus call failed");
292 }
293}
294
SunnySrivastava1984b421bfd2020-03-02 08:59:32 -0600295void EditorImpl::processAndUpdateCI(const std::string& objectPath)
296{
Alpana Kumari414d5ae2021-03-04 21:06:35 +0000297 inventory::ObjectMap objects;
SunnySrivastava1984b421bfd2020-03-02 08:59:32 -0600298 for (auto& commonInterface : jsonFile["commonInterfaces"].items())
299 {
300 for (auto& ciPropertyList : commonInterface.value().items())
301 {
SunnySrivastava1984d076da82020-03-05 05:33:35 -0600302 if (ciPropertyList.value().type() ==
303 nlohmann::json::value_t::object)
SunnySrivastava1984b421bfd2020-03-02 08:59:32 -0600304 {
SunnySrivastava1984d076da82020-03-05 05:33:35 -0600305 if ((ciPropertyList.value().value("recordName", "") ==
306 thisRecord.recName) &&
307 (ciPropertyList.value().value("keywordName", "") ==
308 thisRecord.recKWd))
309 {
Alpana Kumari414d5ae2021-03-04 21:06:35 +0000310 inventory::PropertyMap prop;
311 inventory::InterfaceMap interfaces;
SunnySrivastava1984d076da82020-03-05 05:33:35 -0600312 std::string kwdData(thisRecord.kwdUpdatedData.begin(),
313 thisRecord.kwdUpdatedData.end());
314
Alpana Kumari414d5ae2021-03-04 21:06:35 +0000315 prop.emplace(ciPropertyList.key(), move(kwdData));
316 interfaces.emplace(commonInterface.key(), move(prop));
317 objects.emplace(objectPath, move(interfaces));
SunnySrivastava1984d076da82020-03-05 05:33:35 -0600318 }
SunnySrivastava1984b421bfd2020-03-02 08:59:32 -0600319 }
320 }
321 }
Alpana Kumari414d5ae2021-03-04 21:06:35 +0000322 // Notify PIM
323 common::utility::callPIM(move(objects));
SunnySrivastava1984b421bfd2020-03-02 08:59:32 -0600324}
325
326void EditorImpl::processAndUpdateEI(const nlohmann::json& Inventory,
327 const inventory::Path& objPath)
328{
Alpana Kumari414d5ae2021-03-04 21:06:35 +0000329 inventory::ObjectMap objects;
SunnySrivastava1984b421bfd2020-03-02 08:59:32 -0600330 for (const auto& extraInterface : Inventory["extraInterfaces"].items())
331 {
332 if (extraInterface.value() != NULL)
333 {
334 for (const auto& eiPropertyList : extraInterface.value().items())
335 {
SunnySrivastava1984d076da82020-03-05 05:33:35 -0600336 if (eiPropertyList.value().type() ==
337 nlohmann::json::value_t::object)
SunnySrivastava1984b421bfd2020-03-02 08:59:32 -0600338 {
SunnySrivastava1984d076da82020-03-05 05:33:35 -0600339 if ((eiPropertyList.value().value("recordName", "") ==
340 thisRecord.recName) &&
341 ((eiPropertyList.value().value("keywordName", "") ==
342 thisRecord.recKWd)))
343 {
Alpana Kumari414d5ae2021-03-04 21:06:35 +0000344 inventory::PropertyMap prop;
345 inventory::InterfaceMap interfaces;
SunnySrivastava1984d076da82020-03-05 05:33:35 -0600346 std::string kwdData(thisRecord.kwdUpdatedData.begin(),
347 thisRecord.kwdUpdatedData.end());
Alpana Kumari414d5ae2021-03-04 21:06:35 +0000348 encodeKeyword(kwdData, eiPropertyList.value().value(
349 "encoding", ""));
350
351 prop.emplace(eiPropertyList.key(), move(kwdData));
352 interfaces.emplace(extraInterface.key(), move(prop));
353 objects.emplace(objPath, move(interfaces));
SunnySrivastava1984d076da82020-03-05 05:33:35 -0600354 }
SunnySrivastava1984b421bfd2020-03-02 08:59:32 -0600355 }
356 }
357 }
358 }
Alpana Kumari414d5ae2021-03-04 21:06:35 +0000359 // Notify PIM
360 common::utility::callPIM(move(objects));
SunnySrivastava1984b421bfd2020-03-02 08:59:32 -0600361}
362
363void EditorImpl::updateCache()
364{
365 const std::vector<nlohmann::json>& groupEEPROM =
366 jsonFile["frus"][vpdFilePath].get_ref<const nlohmann::json::array_t&>();
367
Alpana Kumari414d5ae2021-03-04 21:06:35 +0000368 inventory::ObjectMap objects;
SunnySrivastava1984b421bfd2020-03-02 08:59:32 -0600369 // iterate through all the inventories for this file path
370 for (const auto& singleInventory : groupEEPROM)
371 {
Alpana Kumari414d5ae2021-03-04 21:06:35 +0000372 inventory::PropertyMap prop;
373 inventory::InterfaceMap interfaces;
SunnySrivastava1984d076da82020-03-05 05:33:35 -0600374 // by default inherit property is true
375 bool isInherit = true;
376
377 if (singleInventory.find("inherit") != singleInventory.end())
SunnySrivastava1984b421bfd2020-03-02 08:59:32 -0600378 {
SunnySrivastava1984d076da82020-03-05 05:33:35 -0600379 isInherit = singleInventory["inherit"].get<bool>();
380 }
381
382 if (isInherit)
383 {
Santosh Puranik32c46502022-02-10 08:55:07 +0530384 prop.emplace(thisRecord.recKWd, thisRecord.kwdUpdatedData);
385 interfaces.emplace(
386 (IPZ_INTERFACE + (std::string) "." + thisRecord.recName),
387 move(prop));
388 objects.emplace(
389 (singleInventory["inventoryPath"].get<std::string>()),
390 move(interfaces));
SunnySrivastava1984d076da82020-03-05 05:33:35 -0600391
392 // process Common interface
SunnySrivastava1984b421bfd2020-03-02 08:59:32 -0600393 processAndUpdateCI(singleInventory["inventoryPath"]
394 .get_ref<const nlohmann::json::string_t&>());
395 }
396
Santosh Puranik32c46502022-02-10 08:55:07 +0530397 // process extra interfaces
398 processAndUpdateEI(singleInventory,
399 singleInventory["inventoryPath"]
400 .get_ref<const nlohmann::json::string_t&>());
Sunny Srivastava26d6c142021-11-03 15:19:02 -0500401
402 // check if we need to copy some specific records in this case.
403 if (singleInventory.find("copyRecords") != singleInventory.end())
404 {
405 if (find(singleInventory["copyRecords"].begin(),
406 singleInventory["copyRecords"].end(),
407 thisRecord.recName) !=
408 singleInventory["copyRecords"].end())
409 {
410 prop.emplace(thisRecord.recKWd, thisRecord.kwdUpdatedData);
411 interfaces.emplace(
412 (IPZ_INTERFACE + std::string{"."} + thisRecord.recName),
413 move(prop));
414 objects.emplace(
415 (singleInventory["inventoryPath"].get<std::string>()),
416 move(interfaces));
417 }
418 }
SunnySrivastava1984b421bfd2020-03-02 08:59:32 -0600419 }
Alpana Kumari414d5ae2021-03-04 21:06:35 +0000420 // Notify PIM
421 common::utility::callPIM(move(objects));
SunnySrivastava1984b421bfd2020-03-02 08:59:32 -0600422}
423
SunnySrivastava198443306542020-04-01 02:50:20 -0500424void EditorImpl::expandLocationCode(const std::string& locationCodeType)
425{
426 std::string propertyFCorTM{};
427 std::string propertySE{};
428
429 if (locationCodeType == "fcs")
430 {
431 propertyFCorTM =
432 readBusProperty(SYSTEM_OBJECT, "com.ibm.ipzvpd.VCEN", "FC");
433 propertySE =
434 readBusProperty(SYSTEM_OBJECT, "com.ibm.ipzvpd.VCEN", "SE");
435 }
436 else if (locationCodeType == "mts")
437 {
438 propertyFCorTM =
439 readBusProperty(SYSTEM_OBJECT, "com.ibm.ipzvpd.VSYS", "TM");
440 propertySE =
441 readBusProperty(SYSTEM_OBJECT, "com.ibm.ipzvpd.VSYS", "SE");
442 }
443
444 const nlohmann::json& groupFRUS =
445 jsonFile["frus"].get_ref<const nlohmann::json::object_t&>();
Alpana Kumari414d5ae2021-03-04 21:06:35 +0000446 inventory::ObjectMap objects;
447
SunnySrivastava198443306542020-04-01 02:50:20 -0500448 for (const auto& itemFRUS : groupFRUS.items())
449 {
450 const std::vector<nlohmann::json>& groupEEPROM =
451 itemFRUS.value().get_ref<const nlohmann::json::array_t&>();
452 for (const auto& itemEEPROM : groupEEPROM)
453 {
Alpana Kumari414d5ae2021-03-04 21:06:35 +0000454 inventory::PropertyMap prop;
455 inventory::InterfaceMap interfaces;
456 const auto& objectPath = itemEEPROM["inventoryPath"];
457 sdbusplus::message::object_path object(objectPath);
458
SunnySrivastava198443306542020-04-01 02:50:20 -0500459 // check if the given item implements location code interface
Alpana Kumari414d5ae2021-03-04 21:06:35 +0000460 if (itemEEPROM["extraInterfaces"].find(IBM_LOCATION_CODE_INF) !=
SunnySrivastava198443306542020-04-01 02:50:20 -0500461 itemEEPROM["extraInterfaces"].end())
462 {
463 const std::string& unexpandedLocationCode =
Alpana Kumari414d5ae2021-03-04 21:06:35 +0000464 itemEEPROM["extraInterfaces"][IBM_LOCATION_CODE_INF]
SunnySrivastava198443306542020-04-01 02:50:20 -0500465 ["LocationCode"]
466 .get_ref<const nlohmann::json::string_t&>();
467 std::size_t idx = unexpandedLocationCode.find(locationCodeType);
468 if (idx != std::string::npos)
469 {
Alpana Kumari414d5ae2021-03-04 21:06:35 +0000470 std::string expandedLocationCode(unexpandedLocationCode);
SunnySrivastava198443306542020-04-01 02:50:20 -0500471
472 if (locationCodeType == "fcs")
473 {
Alpana Kumari414d5ae2021-03-04 21:06:35 +0000474 expandedLocationCode.replace(
SunnySrivastava198443306542020-04-01 02:50:20 -0500475 idx, 3,
476 propertyFCorTM.substr(0, 4) + ".ND0." + propertySE);
477 }
478 else if (locationCodeType == "mts")
479 {
480 std::replace(propertyFCorTM.begin(),
481 propertyFCorTM.end(), '-', '.');
Alpana Kumari414d5ae2021-03-04 21:06:35 +0000482 expandedLocationCode.replace(
SunnySrivastava198443306542020-04-01 02:50:20 -0500483 idx, 3, propertyFCorTM + "." + propertySE);
484 }
485
Alpana Kumari414d5ae2021-03-04 21:06:35 +0000486 // update the DBUS interface COM as well as XYZ path
487 prop.emplace("LocationCode", expandedLocationCode);
488 // TODO depricate this com.ibm interface later
489 interfaces.emplace(IBM_LOCATION_CODE_INF, prop);
490 interfaces.emplace(XYZ_LOCATION_CODE_INF, move(prop));
SunnySrivastava198443306542020-04-01 02:50:20 -0500491 }
492 }
Alpana Kumari414d5ae2021-03-04 21:06:35 +0000493 objects.emplace(move(object), move(interfaces));
SunnySrivastava198443306542020-04-01 02:50:20 -0500494 }
495 }
Alpana Kumari414d5ae2021-03-04 21:06:35 +0000496 // Notify PIM
497 common::utility::callPIM(move(objects));
SunnySrivastava198443306542020-04-01 02:50:20 -0500498}
499
Santosh Puranika0b23912022-02-10 13:37:09 +0530500void EditorImpl::updateKeyword(const Binary& kwdData, uint32_t offset,
501 const bool& updCache)
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600502{
Santosh Puranika0b23912022-02-10 13:37:09 +0530503 startOffset = offset;
SunnySrivastava1984a0d460e2020-06-03 07:49:26 -0500504#ifndef ManagerTest
Alpana Kumari920408d2020-05-14 00:07:03 -0500505 // TODO: Figure out a better way to get max possible VPD size.
506 Binary completeVPDFile;
507 completeVPDFile.resize(65504);
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600508 vpdFileStream.open(vpdFilePath,
509 std::ios::in | std::ios::out | std::ios::binary);
SunnySrivastava1984a0d460e2020-06-03 07:49:26 -0500510
SunnySrivastava1984e12b1812020-05-26 02:23:11 -0500511 vpdFileStream.seekg(startOffset, ios_base::cur);
Alpana Kumari920408d2020-05-14 00:07:03 -0500512 vpdFileStream.read(reinterpret_cast<char*>(&completeVPDFile[0]), 65504);
513 completeVPDFile.resize(vpdFileStream.gcount());
514 vpdFileStream.clear(std::ios_base::eofbit);
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600515
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500516 vpdFile = completeVPDFile;
Alpana Kumari920408d2020-05-14 00:07:03 -0500517
SunnySrivastava1984a0d460e2020-06-03 07:49:26 -0500518#else
Alpana Kumari920408d2020-05-14 00:07:03 -0500519
SunnySrivastava1984a0d460e2020-06-03 07:49:26 -0500520 Binary completeVPDFile = vpdFile;
Alpana Kumari920408d2020-05-14 00:07:03 -0500521
SunnySrivastava1984a0d460e2020-06-03 07:49:26 -0500522#endif
523 if (vpdFile.empty())
524 {
525 throw std::runtime_error("Invalid File");
526 }
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500527 auto iterator = vpdFile.cbegin();
528 std::advance(iterator, IPZ_DATA_START);
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600529
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500530 Byte vpdType = *iterator;
531 if (vpdType == KW_VAL_PAIR_START_TAG)
532 {
PriyangaRamasamy33c61c22021-04-06 11:15:57 -0500533 ParserInterface* Iparser = ParserFactory::getParser(completeVPDFile);
SunnySrivastava1984e12b1812020-05-26 02:23:11 -0500534 IpzVpdParser* ipzParser = dynamic_cast<IpzVpdParser*>(Iparser);
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600535
SunnySrivastava1984e12b1812020-05-26 02:23:11 -0500536 try
537 {
538 if (ipzParser == nullptr)
539 {
540 throw std::runtime_error("Invalid cast");
541 }
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500542
SunnySrivastava1984e12b1812020-05-26 02:23:11 -0500543 ipzParser->processHeader();
544 delete ipzParser;
545 ipzParser = nullptr;
546 // ParserFactory::freeParser(Iparser);
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500547
SunnySrivastava1984e12b1812020-05-26 02:23:11 -0500548 // process VTOC for PTT rkwd
549 readVTOC();
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500550
SunnySrivastava1984e12b1812020-05-26 02:23:11 -0500551 // check record for keywrod
552 checkRecordForKwd();
553
554 // update the data to the file
555 updateData(kwdData);
556
557 // update the ECC data for the record once data has been updated
558 updateRecordECC();
PriyangaRamasamyc0a534f2020-08-24 21:29:18 +0530559
PriyangaRamasamyc0a534f2020-08-24 21:29:18 +0530560 if (updCache)
561 {
PriyangaRamasamyc0d1c0a2021-04-16 09:45:06 -0500562#ifndef ManagerTest
PriyangaRamasamyc0a534f2020-08-24 21:29:18 +0530563 // update the cache once data has been updated
564 updateCache();
SunnySrivastava1984a0d460e2020-06-03 07:49:26 -0500565#endif
PriyangaRamasamyc0d1c0a2021-04-16 09:45:06 -0500566 }
SunnySrivastava1984e12b1812020-05-26 02:23:11 -0500567 }
568 catch (const std::exception& e)
569 {
570 if (ipzParser != nullptr)
571 {
572 delete ipzParser;
573 }
574 throw std::runtime_error(e.what());
575 }
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500576 return;
577 }
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600578}
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600579} // namespace editor
580} // namespace manager
581} // namespace vpd
Santosh Puranik32c46502022-02-10 08:55:07 +0530582} // namespace openpower